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

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


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


所以我们得到了一个应该被构造的应用程序类


public class Application {


    @Inject

    public Application(SomeDependency one) {


    }


    public static void main(String[] args) {

        DaggerApplicationComponent.create().build();

    }

}


...具有虚拟依赖


public class SomeDependency {


    @Inject

    public SomeDependency() {


    }

}


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


@Component(modules = ApplicationModule.class)

public interface ApplicationComponent {

    Application build();

}

..和一个模块:


@Module

abstract class ApplicationModule {

    @Provides

    static SomeDependency provideDepdendencyOne() {

        return new SomeDependency();

    }

}

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


@Binds 

abstract SomeDependency bindDepdendencyOne(SomeDependency one);

每当我将代码从 更改为@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()

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


慕桂英546537
浏览 209回答 2
2回答

皈依舞

假设您需要@Binds或@Provides首先是错误的。您可以而且应该使用构造函数注入——不是模式,而是Dagger 为我生成代码。您已经有了用 注释的构造函数@Inject,因此 Dagger 知道该类以及如何创建它。没有别的事可做。public class SomeDependency {    @Inject    public SomeDependency() {    }}对于您的这个简单用例,您不需要任何@Provides,不@Binds,甚至不需要 a 。@Module您的示例应该开箱即用,因为两个构造函数都使用@Inject.@Componentpublic interface ApplicationComponent {    Application build();}如果您需要指定范围,可以将其添加到类中。@Provides应该用于不能使用构造函数注入的代码,或者需要额外设置的代码。当然,您可以手动创建所有对象(就像您在示例中所做的那样),但这并没有真正的好处,只会产生很多可以避免的样板。@Binds将与您需要绑定到接口的实现一起使用。最佳情况下,您也可以使用构造函数注入来实现,但您也可以将其添加到组件构建器 ( ) 或在带注释的方法@BindsInstance中创建它。@Provides@Binds MyInterface bindMyImplementation(MyImplementation implementation);

陪伴而非守候

如果您的类标有@Inject构造函数:public class SomeDependency {&nbsp; &nbsp; @Inject // <----&nbsp; &nbsp; public SomeDependency() {&nbsp; &nbsp; }}然后,仅当您需要将其“绑定”为接口的实现或至少与其具体类型不同的类型时,才需要@Binds(或)。@Provides另外,如果你的对象有一个@Inject构造函数,你不需要在模块中实例化它,因为 Dagger 已经知道如何实例化它。因此,要修复您的代码,您需要做的就是:// @Module// abstract class ApplicationModule {//&nbsp; &nbsp; &nbsp;@Provides//&nbsp; &nbsp; &nbsp;static SomeDependency provideDepdendencyOne() {//&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return new SomeDependency();//&nbsp; &nbsp; &nbsp;}// }解决了。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java