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

How to inject implementations from another module

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

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

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

关于如何在不使用构造函数注入的情况下实现这一点有什么想法吗?

简而言之,我刚试过这个,而且有效。请务必检查确切的错误消息并确保您提供了这些接口并且存在 @Inject 注释。

可能只是一些错误的命名接口或缺少注释。接下来是一个完整的示例,使用您描述的架构编译得很好。您当前遇到的问题可能是本 post 最后一部分中描述的问题。如果可能的话,您应该使用第一个解决方案并只添加这些注释。

图书馆

为了可重复性,此示例具有极简模型。一、库模块中我的class需要的接口:

public interface MyInterface {
}

这是我的 class 需要那个界面。确保在构造函数中声明它并提供 @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 的构造函数中声明了库 class 所需的接口。现在我想要一个需要我很棒的库 class 才能使用的 class。我想用匕首注射它。

public class MyTestInjectedClass {

    @Inject
    MyClassUsingMyInterface mMyClassUsingMyInterface;

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

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

注入您无法修改的库

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

public class MyClassUsingMyInterface {
    private MyInterface mMyInterface;

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

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

@Module
public class MyModule {

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

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

这会引入更多代码供我们编写,但会使那些您无法修改的 class 可用。