Reputation: 5721
I would like to pass constructor argument when binding an interface with Impl in Guice.
There are a couple of solutions, but I don't have code access to these interfaces/Impl's. They're developed by other team's and I've included them in My project.
Currently we're using Spring DI and are in the process of moving to Guice. So I need to define something like
<bean name="clientWrapper" class="com.wrapper.client.ClientWrapper">
<constructor-arg index="0" value="${server.ip}" />
<constructor-arg index="1" value="${server.port}" />
</bean>
in Guice. But Pass those Constructor Args.
bind(IClientWrapper.class).to(ClientWrapper.class);
How to achieve this without using Providers?
Upvotes: 3
Views: 3750
Reputation: 14661
Your best option I think is a mix of Provides
methods and toConstructor
binding.
Use the @Provides
method binding when you have an object who has dependencies that can not be worked out by type alone.
public class ProvidesModule extends AbstractModule {
@Provides
IClientWrapper clientWrapper(@Named("server.ip") String ip,
@Named("server.port") int port) {
return new ClientWrapper(ip, port);
}
}
In overall code size this is not significantly more than Spring and is type safe.
When the constructor only has dependencies that can be worked out by type alone then use toConstructor binds
protected void configure() {
try {
bind(TransactionLog.class).toConstructor(
DatabaseTransactionLog.class.getConstructor(DatabaseConnection.class));
} catch (NoSuchMethodException e) {
addError(e);
}
}
One last option:
Our Legacy thingie:
interface LegacyThing {
}
class LegacyThingImp implements LegacyThing {
public LegacyThingImp(String test) {
System.out.println(test);
}
}
Is my magic provider on GitHub. This takes an implementation class and the list of dependencies (as Key
s) and then finds the right constructor by Magic (or reflection).
public class TestMagic {
public static void main(final String... arg) {
Guice.createInjector(
new AbstractModule() {
@Override
protected void configure() {
bind(String.class).annotatedWith(Names.named("testString")).toInstance("Guice!");
bind(LegacyThing.class).toProvider(new MagicLegacyProvider<>(LegacyThingImp.class, Key.get(String.class, Names.named("testString"))));
}
}).getInstance(LegacyThing.class);
}
}
Upvotes: 6