如何避免与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,它是无限实例化的。

好像你会在你的主持人构造函数中调用HomeUi上的字段注入,从而触发一个无限循环,因为这两个对象都不能在没有其他(?)的情况下完成构造。 这看起来像一个非常糟糕的方法,您应该尝试将您的依赖关系移动到对象构造函数中,而不是创建半成品对象。

主要用于不能自己创建的对象,比如使用Android框架types。 恕我直言inject(homeActivity: HomeActivity)应该是你的组件的唯一方法。

循环依赖关系很难管理,并且没有完美的解决方案,但是您可以尝试切换到Provider来延迟依赖关系,并能够以这种方式解决此问题。

下面应该做你想要的,请注意我如何使用构造函数注入,而不是在模块中有2个额外的方法。

 @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, context : Context) { // use with presenter.get() } @Singleton class HomePresenter @Inject constructor(homeUi : HomeUi) 

请注意,使用Provider是解决循环依赖问题的最便宜的方法,但是它可能并不适用于所有情况。

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

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

祝你好运。