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

问题描述 投票:1回答: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();
    }
}

......具有虚拟依赖性

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实现对我来说完全没有意义。我该怎么监督?

提前致谢。

java dagger-2
2个回答
1
投票

假设你首先需要@Binds@Provides,你错了。您可以而且应该使用构造函数注入 - 而不是模式,但Dagger为我生成代码。

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

public class SomeDependency {

    @Inject
    public SomeDependency() {

    }
}

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

@Component
public interface ApplicationComponent {
    Application build();
}

如果需要指定范围,可以在类上添加。


@Provides应该用于不能使用构造函数注入的代码,或者需要额外设置的代码。当然,您可以手动创建所有对象(正如您在示例中所做的那样),但这没有任何实际好处,只会产生许多可以避免的样板。

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

@Binds MyInterface bindMyImplementation(MyImplementation implementation);

1
投票

如果您的类标有@Inject构造函数:

public class SomeDependency {

    @Inject // <----
    public SomeDependency() {

    }
}

然后你需要@Binds(或@Provides),只要你需要“绑定”它作为接口的实现,或者至少是一种不同于其具体类型的类型。

另外,如果你的对象有一个@Inject构造函数,你就不需要在模块中实例化它,因为Dagger已经知道如何实例化它。

因此,要修复代码,您需要做的就是:

// @Module
// abstract class ApplicationModule {
//     @Provides
//     static SomeDependency provideDepdendencyOne() {
//         return new SomeDependency();
//     }
// }

解决了。

© www.soinside.com 2019 - 2024. All rights reserved.