views:

389

answers:

2

What is your advice?

I found most suitable for me solution - keep injectors and modules in enumeration classes. Advantages:

  1. injectors and modules created once,
  2. injectors can be used from different classes while running application (not only at bootstrap),
  3. injectors kept in one place and can be easily found.

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;
}
}
+4  A: 

The bigger question is why?

There should be no need to keep the Injector around, because once the injection is done the Injector should be done and should disappear.

If, however, you really need the Injector, couldn't you simply:

@Inject
private Injector injector;

Is this application web based or is it standalone?

gpampara
This code is used in web also, but not only.About injecting the Injector i asked already question: http://stackoverflow.com/questions/2176216/how-to-inject-injector.The problem is that guice doesn't allow to bind or provide Injector.
Alex M
I have to agree with ColinD, it might be useful to understand how DI works. It's gonna save you a lot of time and effort :)
gpampara
+5  A: 

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.

ColinD
I'm new to DI and Guice, so plz be patient ) 1) It's used in web application, so i need to allocate objects with all dependency graph at runtime, not only at bootstrap. 2) Enum. You shouldn't change modules every time you want to test. For test you can configure separate modules and injectors (if it is needed) . 3) And why i must use injector only for root objects? What about, for instance, AOP?
Alex M