如何避免与Dagger 2的循环依赖?

时间:2017-12-07 20:30:30

标签: android dagger-2

我有以下模块:

@Module
class HomeModule(private val context: Context) {

    @Provides
    fun provideContext() = context

    @Provides
    fun provideHomeUi(): HomeUi {
        return HomeUi()
    }

    @Provides
    @Singleton
    fun provideHomePresenter(homeUi: HomeUi): HomePresenter {
        return HomePresenter(homeUi)
    }
}

HomeUi.kt

中注入的字段
@Inject lateinit var context: Context
@Inject lateinit var presenter: HomePresenter

HomePresenter.kt

中的这个
@Inject lateinit var context: Context

这是我的Deps组件

@Singleton
@Component(modules = arrayOf(
        NetworkModule::class,
        HomeModule::class
))
interface Deps {
    fun inject(homePresenter: HomePresenter)
    fun inject(homeActivity: HomeActivity)
    fun inject(homeUi: HomeUi)
} 

我正在使用Dagger 2.10,但抛出StackOverflowError。我正在寻找一种方法来避免我的循环依赖。

注意:这是我的HomeUi无限实例化。

2 个答案:

答案 0 :(得分:2)

看起来您正在从演示者构造函数中调用#include <iostream> #include <cstdlib> using namespace std; int main() { int N; cin >> N; int i = 1; while (i<=N) { int j = 1; while (j<=N) { cout << "(" << i << "x" << j << ")" << "=" << i*j; if (i*j < 10) cout << "\t\t"; else cout << "\t"; j++; } i++; cout << endl; } system("pause"); return 0; } 上的字段注入,从而触发无限循环,因为没有其他对象(?)都不能完成构造。这看起来非常糟糕,您应该尝试将依赖项移动到对象构造函数中,而不是创建半成品对象。

主要针对您无法自行创建的对象使用字段注入,例如使用Android框架类型。恕我直言HomeUi应该是您组件的唯一方法。

循环依赖很难管理,并且没有完美的解决方案,但你可以尝试切换到inject(homeActivity: HomeActivity)以延迟依赖,并能够以这种方式解决它。

以下内容应该按照您的意图进行,请注意我是如何使用构造函数注入而不是在模块中使用另外两种方法的。

Provider<HomePresenter>

请注意,使用@Singleton @Component(modules = arrayOf( NetworkModule::class, HomeModule::class )) interface Deps { fun inject(homeActivity: HomeActivity) } @Module class HomeModule(private val context: Context) { @Provides fun provideContext() = context } @Singleton class HomeUi @Inject constructor(presenter : Provider<HomePresenter>, context : Context) { // use with presenter.get() } @Singleton class HomePresenter @Inject constructor(homeUi : HomeUi) 是解决我所知道的循环依赖的最便宜的方法,但它可能不适合所有情况。

答案 1 :(得分:1)

我从未将Dagger 2与kotlin一起使用,但我在java中使用它。我通常使用我的视图创建我的模块作为参数,我的方法provideHomeUi()将我的视图作为参数返回。有了这个,你就不应该有StackOverflowError。

顺便说一句,为什么你在Kotlin上使用Dagger 2而不是Kotlin上的DI直接库,比如Kodein,Koin等...

祝你好运。