Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guice: Injecting an object from an installed module to a dependent installed module

I'm quite new to new Guice, but I've been reasonably successful with it until this point.

I have a 'main' Guice module (ServerModule) as follows which installs several other modules:

public class ServerModule extends AbstractModule {

  @Override
  protected void configure() {
    install(new DbModule());
    install(new ModuleA());
    install(new ModuleB());
  }
}

The first installed module (DbModule) is as follows:

public class DbModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(DbService.class).to(DbServiceImpl.class).asEagerSingleton();
  }
}

The issue I am having is that the other two modules depend on the DbService instance created by the DbModule. I.E. I need to inject the DbService object in to the other two installed modules (ModuleA and ModuleB).

As ModuleA and ModuleB are not created by the injector (I am constructing them as shown above), I am unable to inject the DbService instance created into these modules or even pass them in to the constructors. I.E:

install(new DbModule());    
install(new ModuleA(dbService));
install(new ModuleB(dbService)));

I have already experimented with using a provider @provider to provide an instance of DbService, but as I am constructing the modules manually as shown above, it won't work.

If I could get the injector to create ModuleA and ModuleB, I guess I would then be able to inject the DbService instance in to them, but I can't figure out how to do that.

Does anyone have any ideas of how I can best accomplish this?

EDIT: I forgot to mention that the reason @provider seems to be of no use is because I need to use the DbService in ModuleA itself, not in one of it's bindings:

public class ModuleA extends AbstractModule {
  @Inject
  private DbService dbService;

  @Override
  protected void configure() {
    if( dbService.getX() )
      bind(Y.class);
  }
}
like image 324
Joel Avatar asked Oct 02 '22 07:10

Joel


2 Answers

You cannot and should not do this because Guice modules are not supposed to be used this way.

Basically, Guice encourages to separate configuration from actual object creation. You simply cannot inject into modules unless you create an injector, use it to create new modules, and then create another injector with these modules.

And this in fact is very good. Your modules should not usually have complex logic inside them, it is just a configuration, after all. You should refactor your program, for example, to use @Provides-methods or full-fledged Providers. Then you will have much more cleaner dependency configuration logic.

like image 55
Vladimir Matveev Avatar answered Oct 05 '22 22:10

Vladimir Matveev


You can't do that.

The Module.configure() method is called when creating an Injector, and injections could only happen after the Injector is ready to use.

like image 25
niuchl Avatar answered Oct 05 '22 22:10

niuchl