I'm trying to learn Guice, but the following scenario seems hard. Let's say I have classes A,B and C. I should be able to do the following (Note that this example is somewhat simplified to the actual case):
- A is global singleton
- A has dependency on ProviderB (i.e. factory)
- B has dependency on A and ProviderC (i.e. factory)
- C has dependency on A and B
When B creates C, the dependency B of C must be the same instance, i.e. from C's point of view, the B is singleton.
I have tried creating child injectors:
private static class MainModule extends AbstractModule{
@Override
protected void configure() {
bind(A.class).in(Singleton.class);
}
@Provides
B createB(Injector injector){
return injector.createChildInjector(new SubModule()).getInstance(B.class);
}
}
private static class SubModule extends AbstractModule{
@Override
protected void configure() {
bind(B.class).in(Singleton.class);
bind(C.class);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MainModule());
A a = injector.getInstance(A.class);
B b1 = a.getB();
B b2 = a.getB();
// all following C's are different instances
C b1c1 = b1.getC(); //this has b1 and a
C b1c2 = b1.getC(); //this has b1 and a
C b2c1 = b2.getC(); //this has b2 and a
C b2c2 = b2.getC(); //this has b2 and a
}
But then Guice gives errors that B is already bound (The Provides method in MainModule). Therefore I would need to override the B binding of MainModule, but this seems to be impossible using child injectors.
The problem is solvable by using multiple injectors, e.g. create new one for createB method and inject A as parameter, but it seems that using multiple injectors is not best practice.
EDIT: Added comments to C instances to clarify which instance of B they should have
@Provides createB(...)with@Singleton? - Jeff BowmanBhaving aProvider<C>, it would have aCFactoryand could call it likefactory.create(this). - Tavian Barnes