Android Dagger - 没有no-args构造函数的模块

时间:2014-02-05 15:51:50

标签: android dependency-injection dagger

如何组合模块而不使用no-args构造函数。我有一个包含多个模块的库,我想在我的应用程序中重用它。但是,这些模块需要一些参数。以下示例描述了我的设置:

库:

@Module(
    library = true
)
public class LibModule1 {

    private final String mString;

    public LibModule1(String string) {
        mString = string;
    }
    //... provide methods 
}

@Module(
    library = true,
    addsTo = LibraryModule1.class
)
public class LibModule2 {

    private final String mString;

    public LibModule2(String string) {
        mString = string;
    }
    //... provide methods 
}

请注意,LibModule2依赖于LibModule1提供的一些对象。

应用 在我的应用程序中,我将LibModule1和LibModule2中的对象注入一个类。但我不知道,我如何组合这些模块。 includes 参数不起作用,因为两个模块都没有no-args构造函数。 addsTo 不起作用,因为我需要两个库模块,但参数让我只设置一个类。创建两个注入我的类 MyClass.class 的应用程序模块不起作用(一个类只能由一个模块注入,对吧?!)。

@Module(
    injects = MyClass.class
)
public class AppModule {

}

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

您可以完全自由地将模块的实例传递给ObjectGraph.create()和graph.plus()。如果您有有状态的模块,您应该执行以下操作:

ObjectGraph graph = 
    ObjectGraph.create(new LibraryModule1("foo"), LibraryModule2("bar));

也就是说,如果你实例化你在问题中描述的库模块,那么它们在编译时仍会失败,因为它们除非你互相包含(或标记完整 - 假)。你可以简单地让LibModule2包含LibModule1,因为你说它有依赖于后者提供的对象的对象。

@Module(library = true)
public class LibModule1 {

  private final String mString;

  public LibModule1(String string) {
    mString = string;
  }
  //... provide methods 
}

@Module(includes = LibraryModule1.class)
public class LibModule2 {

  private final String mString;

  public LibModule2(String string) {
    mString = string;
  }
  //... provide methods 
}

我建议你在问题中描述的场景中使用complete = false,这样你最终就不会避免使用图形分析了。您只应在创建可重用模块的情况下使用complete = false,该模块需要图形状态,不能直接通过另一个模块包含,因为它将与编译时身份未知的模块组合在一起。

如果您计划在LibModule1的替代方案中使用LibModule2,那么您应该只在此处执行此操作。在上面的例子中,没有特别的理由不在LibModule2中包含LibModule1。

complete = false模块被排除在所有图形分析之外,因为它们没有断言它们的完整性。但如果给出包含,这两个模块都可以完成。但是您必须在实例中传递这些模块,因为它们没有no-args构造函数。

您应该只使用library = true来表示提供的某些绑定是供其他依赖项使用的,而不是通过graph.get(Foo.class)作为图的入口点获取。从本质上讲,库=真正的模块被排除在孤儿绑定分析之外。

答案 1 :(得分:-1)

对不起,我做错了什么。现在它有效。

回答我自己的问题:您需要包含库模块。

@Module(
    injects = MyClass.class,
    includes = {LibModule1.class, LibModule2.class}
)
public class AppModule {

}

在一个模块中,我错过了 complete = false 参数。