Reputation: 279
I am attempting to migrate from Spring to Guice for dependency injection. Here is a sample snippet from a Spring xml config:
<bean id="connectionFactory" class="org.somethirdparty.MyConnectionFactory">
<property name="connectionUrl" value="${urls.connectionUrl}"/>
<property name="ackMode" value="unordered"/>
<property name="timeout" ref="timeoutBean"/>
</bean>
<bean id="timeoutBean" class="java.lang.Integer">
<constructor-arg value="10000"/>
</bean>
I am struggling with figuring out how to parameterize MyConnectionFactory with Google Guice. I cannot annotate the constructor or methods of 'MyConnectionFactory' as this is a class provided by a 3rd party library.
After reading the Guice FAQ it seems to me the only option is to make a Factory for the Factory? That seems silly to me!
Upvotes: 2
Views: 2505
Reputation: 95654
You might need to make a Factory for the MyConnectionFactory, but only if you actually need to vary the parameters passed to MyConnectionFactory at runtime. Otherwise, you can get away with making a Provider
—which is a Factory after all, I guess—or its slimmer cousin the @Provides Method. (I'm guessing the class in question takes unspecific or primitive arguments, or else a toConstructor binding
is yet another possibility.)
The Factory would look like this:
public class MyConnectionFactoryFactory {
@Inject Provider<SomeDependency> someDependencyProvider;
public MyConnectionFactory create(String url) {
return new MyConnectionFactory(someDependencyProvider.get(), url, 10000);
}
}
The Provider would look identical, except it'd implement Provider<MyConnectionFactory>
and create
would instead be a zero-arg get()
. You can bind that through bind(MyConnectionFactory.class).toProvider(MyConnectionFactoryProvider.class)
.
However, if you know all your constructor parameters at configuration time, you could equally create a @Provides
method in your Module, which would look like this:
public class MyModule extends AbstractModule {
@Override public void configure() { /* your configuration here */ }
/* FYI: a @Provides method by any other name would return as sweet */
@Provides MyConnectionFactory getConnectionFactory(SomeDependency dependency) {
return new MyConnectionFactory(dependency, url, 10000);
}
}
...which takes your "wrapper code" boilerplate to three extra non-blank lines. Remember, Guice will automatically bind any combination of X
, Provider<X>
, or @Provides X
to any injection of X
or Provider<X>
automatically for you, so feel free to bind it however is most convenient.
Upvotes: 2