模块依赖于匕首中的另一个模块

2022-09-04 05:24:29

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

如果我有一个用于某些可配置变量的简单模块(例如,我可能想要将其换成测试环境)

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

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

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

@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...
    }
}

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

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

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

简洁:

  • 将值注入一个模块的“正确”方法是什么,这些模块可能来自其他模块?在这里,我使用的是场注入,但我的构造函数注入实验也导致了很多失败。
  • 相关地,何时适合使用 vs. ?addsToincludes

谢谢:)


答案 1

您不需要在一个模块中从另一个模块显式执行任何注入(字段或构造函数)。只需使用 和 。 允许将模块添加到另一个模块并使用它们提供的所有内容。例: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";
    }
}

addsTo与 一起使用。当已经创建了图形并包含一些模块(例如在应用程序类中)时,您可以使用 创建新图形(例如在活动中)。例:ObjectGraph.plus(Object... modules)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();
    }
}

您还可以查看此示例以创建图形范围。


答案 2

推荐