为什么 Dagger 2 强迫我使用 @Provides 而不是 @Binds

cod*_*vic 3 java dagger-2

我现在正在研究 Dagger 2 (Java),一开始就遇到了一个问题。遗憾的是,我在 Dagger 2 文档或 Stackoverflow 上还没有找到任何相关信息,所以如果你们知道一些资源,我将非常感激。

我在此存储库中准备了一个最小的示例来解释我的问题:https://github.com/stackoverflow-samples/dagger2-dependency-cycle

所以我们得到了一个应该构造的Application类

public class Application {

    @Inject
    public Application(SomeDependency one) {

    }

    public static void main(String[] args) {
        DaggerApplicationComponent.create().build();
    }
}

Run Code Online (Sandbox Code Playgroud)

...具有虚拟依赖性

public class SomeDependency {

    @Inject
    public SomeDependency() {

    }
}

Run Code Online (Sandbox Code Playgroud)

当然还有 Dagger 类/接口......组件接口:

@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    Application build();
}
Run Code Online (Sandbox Code Playgroud)

..和一个模块:

@Module
abstract class ApplicationModule {
    @Provides
    static SomeDependency provideDepdendencyOne() {
        return new SomeDependency();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白的是为什么 Dagger 强制我使用注释注册SomeDepdendency并且@Provides不允许通过以下方式注册@Binds:

@Binds 
abstract SomeDependency bindDepdendencyOne(SomeDependency one);
Run Code Online (Sandbox Code Playgroud)

每当我将代码更改为 时,@Provides它@Binds都会出现以下错误:

[Dagger/DependencyCycle] Found a dependency cycle:
      io.github.codejanovic.dagger2.example.SomeDependency is injected at
          io.github.codejanovic.dagger2.example.ApplicationModule.bindDepdendencyOne(one)
      io.github.codejanovic.dagger2.example.SomeDependency is injected at
          io.github.codejanovic.dagger2.example.Application(one)
      io.github.codejanovic.dagger2.example.Application is provided at
          io.github.codejanovic.dagger2.example.ApplicationComponent.build()
Run Code Online (Sandbox Code Playgroud)

无法@Bind实施对我来说绝对没有意义。我负责监督什么?

提前致谢。

Dav*_*jak 6

你一开始就假设你需要@Binds或者是错误的。@Provides您可以而且应该使用构造函数注入——不是模式,而是Dagger 为我生成代码。

您已经有了用 注释的构造函数@Inject,因此 Dagger 知道该类以及如何创建它。没有其他事可做。

public class SomeDependency {

    @Inject
    public SomeDependency() {

    }
}
Run Code Online (Sandbox Code Playgroud)

对于您的这个简单用例,您不需要任何@Provides,不@Binds,甚至不需要。@Module您的示例应该可以开箱即用,因为两个构造函数都用 进行注释@Inject。

@Component
public interface ApplicationComponent {
    Application build();
}
Run Code Online (Sandbox Code Playgroud)

如果您需要指定范围,可以将其添加到类中。


@Provides应用于无法使用构造函数注入或需要额外设置的代码。当然,您可以手动创建所有对象(正如您在示例中所做的那样),但这没有真正的好处,只会产生大量可以避免的样板文件。

@Binds与需要绑定到接口的实现一起使用。最好也使用构造函数注入来实现,但您也可以将其添加到组件构建器 ( @BindsInstance) 或在带注释的方法中创建它@Provides。

@Binds MyInterface bindMyImplementation(MyImplementation implementation);
Run Code Online (Sandbox Code Playgroud)