Java 模块依赖于 Dagger 中的另一个模块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24668957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 13:57:45  来源:igfitidea点击:

Module depending on another module in Dagger

javaandroiddependency-injectiondagger

提问by pablo.meier

I'm trying to use Daggerto do Dependency Injection on an app that I'm building, and running into trouble constructing proper DAGs when I have one package's Module depending on values provided by the Injector (presumably provided by another Module).

我正在尝试使用Dagger在我正在构建的应用程序上进行依赖注入,并且当我根据注入器提供的值(可能由另一个模块提供)有一个包的模块时,在构建正确的 DAG 时遇到了麻烦。

If I have a simple module for some configurable variables (that I might want to swap out for testing environments, for example)

如果我有一些可配置变量的简单模块(例如,我可能想换出测试环境)

@Module(
    injects = DependentModule.class,
)
public class ConfigModule {

    @Provides @Named("ConfigOption") String provideConfigOption() {
        return "This Module's configurable option!";
    }
}

and another module depends on it, e.g.

另一个模块依赖于它,例如

@Module(
    injects = {
            TopLevelClass.class
    }
)
public class DependentModule {

    @Inject @Named("ConfigOption") String configOption;

    public DependentModule() {
        ObjectGraph.create(this).inject(this);
        doSomethingWithConfig(configOption);
    }

    @Provides @Singleton UsefulValue provideUsefulValue() {
        // Whatever this module needs to do...
    }
}

The line where I try to bootstrap the injection in the constructor fails, and it complains that I haven't specified an explicit injectsline in a proper module.

我尝试在构造函数中引导注入的行失败,它抱怨我没有injects在适当的模块中指定显式行。

Through trial-and-error I see this goes away if in @ModuleI add a line include = ConfigModule.class, but this strikes me as semantically wrong, since a) the DAG I'll be creating will now include the values of both modules, rather than just one, and b) it defeats the purpose/flexibility of DI in the first place to link a specific Module rather than simply let Dagger inject the appropriate value.

通过反复试验,如果@Module我添加一行include = ConfigModule.class,我发现这会消失,但这在我看来是语义错误的,因为 a) 我将创建的 DAG 现在将包含两个模块的值,而不仅仅是一个, b) 它首先违背了 DI 的目的/灵活性来链接特定的模块,而不是简单地让 Dagger 注入适当的值。

I'm presuming I shouldn't be creating an Object Graph with thisonly to inject into it? But then I run into the issue of not linking a specific Module...

我假设我不应该创建一个对象图this只是为了注入它?但是后来我遇到了不链接特定模块的问题......

Succinctly:

简而言之:

  • What is the 'proper' way to Inject values into one Modules that may be provided from other Modules? Here I'm using field injection, but my experiments with constructor injection have also resulted in a lot of failure.
  • Relatedly, when is it appropriate to use addsTovs. includes?
  • 将值注入可能从其他模块提供的一个模块中的“正确”方法是什么?这里我使用了字段注入,但是我对构造函数注入的实验也导致了很多失败。
  • 相关地,什么时候使用addsTovs合适includes

Thanks :)

谢谢 :)

采纳答案by Kirill Boyarshinov

You don't need to do any of injection (field or constructor) in one module from another explicitly. Just use addsToand includes. includesallows to add modules to another and use everything they provide. Example:

您不需要从另一个模块中明确地在一个模块中执行任何注入(字段或构造函数)。只需使用addsToincludesincludes允许将模块添加到另一个模块并使用它们提供的所有内容。例子:

@Module()
public class ModuleA {
    @Provides @Named("ValueA") String provideValueA() {
        return "This is ValueA";
    }
}

@Module(
    includes = ModuleA.class
)
public class ModuleB {
    // ValueA comes from ModuleA
    @Provides @Named("ValueB") String provideValueB(@Named("ValueA") String valueA) {
        return valueA + " and ValueB";
    }
}

addsTois used with ObjectGraph.plus(Object... modules). When graph is already created and contains some modules (e.g. in Application class), you can create new graph (e.g. in Activity) using plus. Example:

addsTo与 一起使用ObjectGraph.plus(Object... modules)。当图已经创建并包含一些模块(例如在 Application 类中)时,您可以使用plus. 例子:

@Module()
public class ApplicationModule {
    @Provides @Named("ValueA") String provideValueA() {
        return "This is ValueA";
    }
}

@Module(
    addsTo = ApplicationModule.class
)
public class ActivityModule {
    // ValueA comes from ApplicationModule
    @Provides @Named("ValueB") String provideValueB(@Named("ValueA") String valueA) {
        return valueA + " and ValueB";
    }
}

public class DemoApplication extends Application {
  private ObjectGraph graph;

  @Override public void onCreate() {
     super.onCreate();
     graph = ObjectGraph.create(getModules().toArray());
  }

  protected List<Object> getModules() {
      return Arrays.asList(
          new ApplicationModule()
      );
  }

  public void inject(Object object) {
      graph.inject(object);
  }

  public ObjectGraph getObjectGraph() {
      return graph;
  }
}

public class DemoActivity extends Activity {
    private ObjectGraph activityGraph;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create the activity graph by .plus-ing our modules onto the application graph.
        DemoApplication application = (DemoApplication) getApplication();
        activityGraph = application.getApplicationGraph().plus(new ActivityModule());

        // Inject ourselves so subclasses will have dependencies fulfilled when this method returns.
        activityGraph.inject(this);
    }

    @Override protected void onDestroy() {
        // Eagerly clear the reference to the activity graph to allow it to be garbage collected as
        // soon as possible.
        activityGraph = null;
        super.onDestroy();
    }
}

Also you can check thisexample to create scopes of graphs.

您也可以检查示例以创建图形范围。