我有两个类,Foo<T>和Bar,它们相互依赖,以及各种其他类。我使用Dagger-2进行依赖注入,但是如果我天真地添加循环依赖,Dagger在运行时会遇到堆栈溢出。有什么好方法可以重构类来修复这个问题,同时仍然使用Dagger注入所有其他依赖项,并且对现有调用的重复和更改最少?
发布于 2017-06-23 05:42:36
最简单的解决方法是在一端使用Lazy<T>。
Lazy<Foo> foo;
@Inject
Bar(Lazy<Foo> foo) {
this.foo = foo;
}
// use foo.get(); when needed发布于 2017-06-23 05:29:39
在与同事进行了大量的思考和交谈后,我们最终完成了以下工作:
class Foo<T> extends FooWithoutDep<T> {
@Inject Foo(Bar bar, OtherDep1 dep1, OtherDep2 dep2) {
super(dep1, dep2);
setBarDep(bar);
}
}
class FooWithoutDep<T> {
//Field declarations elided
@Inject FooWithoutDep(OtherDep1 dep1, OtherDep2 dep2) {
//Normal constructor stuff
}
void setBarDep(Bar bar) { this.bar = bar; }
//The rest of the actual logic
}
class Bar {
//Field declarations elided
@Inject Bar(FooWithoutDep<Thing> foo, OtherDep3 dep3) {
this.foo = foo;
this.foo.setBarDep(this);
this.dep3 = dep3;
}
//Code that uses Foo and the other dependencies
}为了解释这一点--我们将Foo的实际逻辑移到了一个父类(FooWithoutDep)中,这个父类将循环依赖项作为可设置字段而不是构造函数参数。然后,原始类只包含一个构造函数,该构造函数接受循环依赖并调用setter。另一个类Bar依赖于父类(FooWithoutDep),并显式地调用setter,传递给自己(this)。这使得对类的所有现有引用都保持不变,同时仍然使用Dagger注入所有依赖项。
这看起来足够令人困惑,值得在这里写下来。
发布于 2018-08-16 11:15:38
这就是我解决这个问题的方法,没有父类。
第一类:引擎。(在组件接口中)
@Provides
public Engine myEngine(Context context) {
return new Engine (context);
}第二类:零件。Engine也需要Parts实例,但创建被延迟了。
@Inject
public Parts(Context context, Engine engine) {
this.context = context;
this.engine= engine;
engine.setParts(this);
}循环依赖是可以实现的,但必须先启动一个类,然后再启动另一个类。
同样,如果可能的话,重构代码以避免循环DI。
https://stackoverflow.com/questions/44709685
复制相似问题