I have been looking over the net for an explanation about the injector heirarchy and how/when to use createChildInjector(), but I cannot find a clear and concise explanation.
Here is my use case:
For example, say the database search module contains:
bind(PlaceSearch.class).to(HibernatePlaceSearch.class);
bind(PersonSearch.class).to(HibernatePersonSearch.class);
And the ElasticSearch module contains:
bind(PersonSearch.class).to(PersonElasticSearch.class);
Is there a way to create an injector that includes the PlaceSearch binding from the database search module and the PersonSearch binding from the ElasticSearch module without creating a separate module that contains
bind(PlaceSearch.class).to(HibernatePlaceSearch.class);
bind(PersonSearch.class).to(PersonElasticSearch.class);
? Is this a case for Modules.override()? A case for createChildInjector? Thanks ahead of time!
Hierarchical dependency injection enables you to share dependencies between different parts of the application only when and if you need to.
You can configure providers for different injectors in the injector hierarchy. An internal platform-level injector is shared by all running apps. The AppModule injector is the root of an app-wide injector hierarchy, and within an NgModule, directive-level injectors follow the structure of the component hierarchy.
getInstance. Returns the appropriate instance for the given injection type; equivalent to getProvider(type). get() . When feasible, avoid using this method, in favor of having Guice inject your dependencies ahead of time.
The Modules.override()
is not working in Stage.PRODUCTION
. You should use PrivateModule
where the binding is valid/visible only inside private module, so you can bind different implementation classes to the same interface. Then you can install the Private module to the parent Module, but you have to explicitly expose()
all binding you want to make visible for other modules.
Guice - Private Modules
Lets say:
DatabaseSearchModule.java (extends PrivateModule)
bind(PlaceSearch.class).annotatedWith(Names.named("dbSearch")).to(HibernatePlaceSearch.class);
bind(PersonSearch.class).to(HibernatePersonSearch.class);
expose(PlaceSearch.class).annotatedWith(Names.named("dbSearch"));
EleasticSearchModule.java (extends PrivateModule)
bind(PersonSearch.class).annotatedWith(Names.named("elastic")).to(PersonElasticSearch.class);
expose(PersonSearch.class).annotatedWith(Names.named("elastic"));
Well then you can install it in some Parent abstract or servlet module
MainModule.java
install(new DatabaseSearchModule());
install(new EleasticSearchModule());
bind(OtherClass.class);
OtherClass.java
@Inject @Named("elastic")
private PlaceSearch elasticSearch;
@Inject @Named("dbSearch")
private PlaceSearch dbSearch;
You can use Named
annotation or you can create very elegant own binding Annotation.
This is a perfect case for Modules.override()
.
Most applications shouldn't use child injectors. They add a lot of configuration complexity and have some surprising behavior for corner cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With