Android 如何使用Dagger 2避免循环依赖?

Android 如何使用Dagger 2避免循环依赖?,android,dagger-2,Android,Dagger 2,我有以下模块: @Module class HomeModule(private val context: Context) { @Provides fun provideContext() = context @Provides fun provideHomeUi(): HomeUi { return HomeUi() } @Provides @Singleton fun provideHomePresent

我有以下模块:

@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
@Inject lateinit var context: Context
这一个在
HomePresenter.kt

@Inject lateinit var context: Context
@Inject lateinit var presenter: HomePresenter
@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,但是抛出了一个
StackOverflowerError
。我正在寻找一种避免循环依赖的方法


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

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

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


祝你好运。

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

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


祝你好运。

似乎你将从presenters构造函数中调用
HomeUi
上的字段注入,从而触发一个无限循环,因为没有另一个对象(?)两个对象都无法完成构造。这看起来是一种非常糟糕的方法,您应该尝试将依赖项移动到对象构造函数中,而不是创建半成品对象

字段注入主要用于无法自己创建的对象,例如Android框架类型。IMHO
inject(homeActivity:homeActivity)
应该是组件的唯一方法

循环依赖关系很难管理,也没有完美的解决方案,但您可以尝试切换到
提供程序
来延迟依赖关系,并以这种方式解决它

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

@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)
@Singleton
@组件(模块=阵列)(
NetworkModule::类,
HomeModule::类
))
接口Deps{
乐趣注入(家庭活动:家庭活动)
}
@模块
类HomeModule(专用val上下文:上下文){
@提供
fun provideContext()=上下文
}
@独生子女
类HomeUi@Inject构造函数(演示者:提供程序,上下文:上下文)
{
//与presenter.get()一起使用
}
@独生子女
类HomePresenter@Inject构造函数(homeUi:homeUi)

请注意,使用
提供程序
是解决我所知道的循环依赖关系的最便宜的方法,但它可能不适合于所有情况。

似乎您将从presenters构造函数中调用
HomeUi
上的字段注入,因此触发了一个无限循环,因为没有另一个对象(?)两个对象都无法完成构造。这看起来是一种非常糟糕的方法,您应该尝试将依赖项移动到对象构造函数中,而不是创建半成品对象

字段注入主要用于无法自己创建的对象,例如Android框架类型。IMHO
inject(homeActivity:homeActivity)
应该是组件的唯一方法

循环依赖关系很难管理,也没有完美的解决方案,但您可以尝试切换到
提供程序
来延迟依赖关系,并以这种方式解决它

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

@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)
@Singleton
@组件(模块=阵列)(
NetworkModule::类,
HomeModule::类
))
接口Deps{
乐趣注入(家庭活动:家庭活动)
}
@模块
类HomeModule(专用val上下文:上下文){
@提供
fun provideContext()=上下文
}
@独生子女
类HomeUi@Inject构造函数(演示者:提供程序,上下文:上下文)
{
//与presenter.get()一起使用
}
@独生子女
类HomePresenter@Inject构造函数(homeUi:homeUi)

请注意,使用
提供程序
是解决我所知道的循环依赖关系的最便宜的方法,但它可能并不适用于所有情况。

我遵循了您的方法,仅对我无法创建的对象使用inject(),而且看起来确实更好。谢谢你的建议!我遵循了您的方法,只对我无法创建的对象使用inject(),而且看起来确实更好。谢谢你的建议!