如何从另一个模块注入实现

时间:2016-02-06 11:01:48

标签: java dependency-injection dagger-2

我有一个基于Dagger 2的项目,该项目由两个模块组成。核心模块包括一些接口和一些为这些接口声明成员注入的类。

这些接口的实际实现包含在第二个模块中,这是一个Android项目。因此,Android项目中包含这些的提供方法。

Dagger会在编译期间抱怨不知道如何在核心模块中注入这些内容。

关于如何在不使用构造函数注入的情况下实现此目的的任何想法?

1 个答案:

答案 0 :(得分:1)

简而言之,我只是尝试了这一点,并且它有效。请务必检查确切的错误消息,并确保提供这些接口并且存在@Inject注释。

可能只有一些错误的命名界面或缺少注释。跟进是一个完整的示例,使用您描述的编译正常的架构。您目前遇到的问题可能是本文最后一部分中描述的问题。如果可能,您应该使用第一个解决方案,然后添加这些注释。

图书馆

对于可重复性,此样本具有极简主义模型。首先,我的类在库模块中需要的接口:

public interface MyInterface {
}

这是我的类,需要该接口。确保在构造函数中声明它并提供@Inject注释!

@MyScope // be sure to add scopes in your class if you use constructor injection!
public class MyClassUsingMyInterface {
    private MyInterface mMyInterface;

    @Inject
    public MyClassUsingMyInterface(MyInterface myInterface) {
        mMyInterface = myInterface;
    }
}

我们的想法是,界面将由应用程序使用MyClassUsingMyInterface实现,并由dagger提供。代码很好地解耦了,我的功能很少的库很棒。

应用程序

这里需要提供实际的耦合。这意味着要获得MyClassUsingMyInterface我们必须确保提供MyInterface。让我们从提供该模块的模块开始:

@Module
public class MyModule {

    @Provides
    MyInterface providesMyInterface() {
        return new MyInterface() {
            // my super awesome implementation. MIT license applies.
        };
    }
}

为了实际使用它,我们提供了一个可以注入MyTestInjectedClass的组件,它将需要MyClassUsingMyInterface

@Component(modules = MyModule.class)
public interface MyComponent {

    void inject(MyTestInjectedClass testClass);
}

现在我们有办法提供所请求的界面。我们在标有@Inject的构造函数中声明了库类所需的接口。现在我想要一个需要我很棒的库类的类。我想用匕首注射它。

public class MyTestInjectedClass {

    @Inject
    MyClassUsingMyInterface mMyClassUsingMyInterface;

    void onStart() {
        DaggerMyComponent.create().inject(this);
    }
}

现在我们点击编译......并且dagger将创建所需的所有工厂。

注入您无法修改的库

为了提供完整的匕首,这个样本也可能没有实际访问库的源代码。如果没有@Inject注释,则匕首将很难创建对象。注意缺少的注释:

public class MyClassUsingMyInterface {
    private MyInterface mMyInterface;

    public MyClassUsingMyInterface(MyInterface myInterface) {
        mMyInterface = myInterface;
    }
}

在这种情况下,我们必须手动提供课程。该模块需要修改如下:

@Module
public class MyModule {

    @Provides
    MyInterface providesMyInterface() {
        return new MyInterface() {
        };
    }

    @Provides
    MyClassUsingMyInterface providesMyClass(MyInterface myInterface) {
        return new MyClassUsingMyInterface(myInterface);
    }
}

这为我们编写了更多代码,但会使这些类无法修改。