我现在正在研究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
实现对我来说绝对没有意义。我要监督什么?
谢谢。
答案 0 :(得分: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 :(得分:1)
如果您的班级被标记为@Inject
构造函数:
public class SomeDependency {
@Inject // <----
public SomeDependency() {
}
}
然后,仅当您需要将其“绑定”作为接口的实现或至少不同于其具体类型的类型时,才需要@Binds
(或@Provides
)。
此外,如果您的对象具有@Inject
构造函数,则您无需在模块中实例化它,因为Dagger已经知道如何实例化它。
因此,要修复代码,您需要做的只是:
// @Module
// abstract class ApplicationModule {
// @Provides
// static SomeDependency provideDepdendencyOne() {
// return new SomeDependency();
// }
// }
已解决。