Reputation: 3442
If I create a provider and bind it to a class, like this
bind(MyClass.class).toProvider(MyClassProvider.class)
then Provider<MyClass>
automatically be bound to MyClassProvider
. That's a problem if you want to inject a Provider<MyClass>
into MyClassProvider
, like this:
@Inject
public MyClassProvider(Provider<MyClass> provider)
I want to inject the default Guice provider into my provider so I can easily create new instances inside my custom provider. How to do that?
Upvotes: 4
Views: 5535
Reputation: 14661
You will need to use a binding annotation on one of the two. If you don't mind the users of MyClass being annotated it is quite easy.
public class AccountTest {
@Test
public void test() {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(MyClass.class).annotatedWith(Names.named("MYPROVIDER")).toProvider(MyClassProvider.class);
}
});
MyClassUser user = injector.getInstance(MyClassUser.class);
assertTrue(user.get().myProvider); // Shows if was created via my provider or the Guice provider.
}
}
class MyClassUser {
Provider<MyClass> provider;
@com.google.inject.Inject
public MyClassUser(@Named("MYPROVIDER") Provider<MyClass> provider) {
this.provider= provider;
}
MyClass get() {
return provider.get();
}
}
class MyClass {
boolean myProvider = false;
}
class MyClassProvider implements Provider<MyClass> {
Provider<MyClass> provider;
@com.google.inject.Inject
public MyClassProvider(Provider<MyClass> provider) {
this.provider= provider;
}
@Override
public MyClass get() {
MyClass c = provider.get();
c.myProvider = true;
return c;
}
public String toString() {
return "Our provider";
}
}
If you don't want the users of MyClass to use a named provider the only way I've been able to get it to work was to extend MyClass
and have MyClassProvider
require a "MyClass2
" Provider. As a solution it smells, but worked (rather than pollute this answer with a bad answer, you can find the code on this gist).
You may be able to do this with with private modules or child modules (as it is a variant on the Robot Legs problem) but I've been unable to work out how to do this.
Upvotes: 4