Does GIN support anything like child injectors?
Question
I have one application that contains sub-applications. I would like to segregate the GIN injection so that each sub-application can have separate instances of the same core shared classes. I also want the injector to supply classes from some core modules to all sub-applications, so that singleton instances can be shared. e.g.
GIN Modules:
Core - shared
MetadataCache - one per sub-application
UserProvider - one per sub-application
In Guice I can do this using createChildInjector
, but I can't see an obvious equivalent in GIN.
Can I achieve something similar in GIN?
Solution
Here it is on SOF http://code.google.com/p/google-gin/wiki/PrivateModulesDesignDoc. Hope it helps you out.
OTHER TIPS
I solved this thanks to the link given by @Abderrazakk, but as the link isn't very forthcoming with instructions I thought I'd add a sample solution here too:
Private GIN modules allow you to have a single level of hierarchical injection, where types registered inside a private module are only visible to other instances created within that module. Types registered inside any non-private modules are still available to all.
Example
Let's have some sample types to inject (and inject into):
public class Thing {
private static int thingCount = 0;
private int index;
public Thing() {
index = thingCount++;
}
public int getIndex() {
return index;
}
}
public class SharedThing extends Thing {
}
public class ThingOwner1 {
private Thing thing;
private SharedThing shared;
@Inject
public ThingOwner1(Thing thing, SharedThing shared) {
this.thing = thing;
this.shared = shared;
}
@Override
public String toString() {
return "" + this.thing.getIndex() + ":" + this.shared.getIndex();
}
}
public class ThingOwner2 extends ThingOwner1 {
@Inject
public ThingOwner2(Thing thing, SharedThing shared) {
super(thing, shared);
}
}
Create two private modules like this (using ThingOwner2 for the second one):
public class MyPrivateModule1 extends PrivateGinModule {
@Override
protected void configure() {
bind(Thing.class).in(Singleton.class);
bind(ThingOwner1.class).in(Singleton.class);
}
}
And a shared module:
public class MySharedModule extends AbstractGinModule {
@Override
protected void configure() {
bind(SharedThing.class).in(Singleton.class);
}
}
Now register the two modules in our injector:
@GinModules({MyPrivateModule1.class, MyPrivateModule2.class, MySharedModule.class})
public interface MyGinjector extends Ginjector {
ThingOwner1 getOwner1();
ThingOwner2 getOwner2();
}
Finally we can look and see that both ThingOwner1 and ThingOwner2 instances have the same SharedThing instance from the shared module, but different Thing instances from their private registrations:
System.out.println(injector.getOwner1().toString());
System.out.println(injector.getOwner2().toString());