我正在研究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
实现对我来说完全没有意义。我该怎么监督?
提前致谢。
假设你首先需要@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);
如果您的类标有@Inject
构造函数:
public class SomeDependency {
@Inject // <----
public SomeDependency() {
}
}
然后你需要@Binds
(或@Provides
),只要你需要“绑定”它作为接口的实现,或者至少是一种不同于其具体类型的类型。
另外,如果你的对象有一个@Inject
构造函数,你就不需要在模块中实例化它,因为Dagger已经知道如何实例化它。
因此,要修复代码,您需要做的就是:
// @Module
// abstract class ApplicationModule {
// @Provides
// static SomeDependency provideDepdendencyOne() {
// return new SomeDependency();
// }
// }
解决了。