What is your advice?
I found most suitable for me solution - keep injectors and modules in enumeration classes. Advantages:
Example:
import static ru.package.Modules.*;
public enum Injectors {
FOO_INJECTOR(BarModule.module()),
FOO2_INJECTOR(FOO_INJECTOR.injector(),
Bar2Module.module(), FooModule.module());
private final Injector m_injector;
Injectors (Module... modules) {
m_injector = Guice.createInjector(modules);
}
Injectors (Injector parentInjector, Module... modules) {
m_injector = parentInjector.createChildInjector(modules);
}
public Injector injector() {
return m_injector;
}
}
The injector tracks the dependencies for each type and uses bindings to inject them. This is the core of Guice, although you rarely interact with it directly. This "behind-the-scenes" operation is what distinguishes dependency injection from its cousin, the service locator pattern.
The implementation is very easy to understand. We need to create Injector object using Guice class createInjector() method where we pass our injector class implementation object. Then we use injector to initialize our consumer class. If we run above class, it will produce following output.
Using GuiceIn each of your constructors that need to have something injected in them, you just add an @Inject annotation and that tells Guice to do it's thing. Guice figures out how to give you an Emailer based on the type. If it's a simple object, it'll instantiate it and pass it in.
Annotation Type Inject. @Target(value={METHOD,CONSTRUCTOR,FIELD}) @Retention(value=RUNTIME) @Documented public @interface Inject. Annotates members of your implementation class (constructors, methods and fields) into which the Injector should inject values.
You appear to be fundamentally misunderstanding how dependency injection works. If you are trying to use a reference to Injector
anywhere in your code besides the place where you bootstrap the application, you're not using dependency injection, you're using it as a Service Locator instead. You're forced to prepare an Injector
whenever you need to test a class and your classes do not make it clear in their constructors exactly what their dependencies are (since who knows what they'll get out of the Injector
in some method if they have or can get a reference to it). Actually, using enum
as you've described here is even worse than that: you cannot change the configuration at all, even for testing, because your modules are hardcoded into the enum.
With dependency injection, classes declare their dependencies only and allow the Injector
, working transparently (after the initial call to get the root application object), to provide all those dependencies. This makes understanding, testing and changing functionality in your code relatively easy. Anyway, I'd suggest learning more about how DI and Guice are intended to be used... you really should not want to do this.
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