简体   繁体   中英

Is it possible to inject value to modules

I have a Module that uses a flag to decide whether or not to install another module. Is there a way to achive that by injection, or do I need to explicitly pass the flag's value in the ctor?

 public class MyModule implements Module {

    private final Boolean shouldInstallOtherModule;

    @Inject public MyModule(Boolean shouldInstallOtherModule) {
        this.shouldInstallOtherModule = shouldInstallOtherModule;
    }

    public void configure() {
      if(shouldInstallOtherModule) {
       install(SomeOtherModule);       
       }

    }
}

Though it is possible to inject into a Module, or to get a Module from an Injector, it's a much better design decision not to: Modules can access their own injectors in limited ways, so having @Inject methods and fields on a Module introduces a second Injector and that could become confusing very quickly.

In this situation, I would create an Injector for the configuration alone, then create a child injector with Modules based on that configuration. Your Module should be responsible for configuring bindings, not choosing which other Modules to install—that's a job better left for the root application.

If you feel you must keep the conditional install ation in a Module, just take the configuration value directly as a constructor parameter and let your top-level object (that creates your injector) provide it however it needs. This will prevent two Injectors from being active in the same object instance at the same time, which makes everything easier to understand.

For similar problems and solutions, see this SO question: "Accessing Guice injector in its Module?"

Well, I would suggest you to have a look at Netflix Governator framework . The configuration would look like this:

LifecycleInjector injector = LifecycleInjector.builder()
          .withModuleClass(MyModule.class)
          .withBootstrapModule(new InitializationModule()).build();

where InitializationModule:

public class InitializationModule implements BootstrapModule {

    public void configure() {
      bind(Boolean.class).toInstance(readFromConfig());
    }
}

Or better you can use Configuration feature

which would look like this

 public class MyModule implements Module {
    //read from config.properties
    @Configuration("configs.shouldInstallOtherModule")
    private final Boolean shouldInstallOtherModule;

    public void configure() {
      if(shouldInstallOtherModule) {
       install(SomeOtherModule);       
       }

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM