Reputation:
I have a Guice whose constructor accept an injected argument:
@Singleton
public class MyClass {
private MyConfiguration myConfiguration;
@Inject
public MyClass(MyConfiguration myConfiguration) {
this.myConfiguration = myConfiguration;
}
}
Now, I want to be able to inject the argument depends on the environment I run this. In Test, I want to inject a MyConfiguration object while in production I want to inject another object.
I have got two providers for MyConfiguration. The MyConfigurationProvider reads a external configuration file and get the config from there. The MyConfigurationTestProvider just hard code all the settings.
I don't know how to config this though. I tried to do a binding in the Guice module like:
public class MyGuiceModule extends AbstractModule {
@Override
protected void configure() {
bind(MyConfiguration.class).toProvider(MyConfigurationProvider.class).in(Singleton.class);
}
}
And in the Guice module of the test, use:
public class MyGuiceTestModule extends AbstractModule {
@Override
protected void configure() {
install(new MyGuiceModule());
bind(MyConfiguration.class).toProvider(MyConfigurationTestProvider.class).in(Singleton.class);
}
}
But this gave me an error of binding more than one provider.
My question is that how I can use different provider for same object depends on environment?
Many thanks.
Upvotes: 1
Views: 1862
Reputation: 127781
Yes, Guice modules cannot contain multiple bindings with the same key by default. However, you can use override feature of modules when creating your injector. This feature was designed exactly for this purpose.
Remove install()
thing from your test module and create an injector for your test environment like this:
Injector injector = Guice.createInjector(Modules.override(new MyGuiceModule()).with(new MyGuiceTestModule()));
With this your binding for MyConfiguration
from test module will replace the binding from production module.
Upvotes: 4