Reputation: 1223
I have the following Module :
@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)
}
}
Those injected fields in HomeUi.kt
@Inject lateinit var context: Context
@Inject lateinit var presenter: HomePresenter
And this one in HomePresenter.kt
@Inject lateinit var context: Context
Here my Deps Component
@Singleton
@Component(modules = arrayOf(
NetworkModule::class,
HomeModule::class
))
interface Deps {
fun inject(homePresenter: HomePresenter)
fun inject(homeActivity: HomeActivity)
fun inject(homeUi: HomeUi)
}
I am using Dagger 2.10 but a StackOverflowError
is thrown. I am looking for a way to avoid my circular dependency.
Note : This is my HomeUi which is infinitely instantiate.
Upvotes: 0
Views: 3338
Reputation: 34532
It seems like you'd be calling field injection on HomeUi
from within your presenters constructor, thus triggering an infinite loop since neither object can finish being constructed without the other (?). This looks like a really bad approach and you should try to move your dependencies into the objects constructors instead of creating half-finished objects.
Use field injection primarily for objects that you can't create yourself, e.g. with Android framework types. IMHO inject(homeActivity: HomeActivity)
should be the only method of your component.
Cyclic dependencies are hard to manage and there is no perfect solution, but you can try things like switching to Provider<HomePresenter>
to delay the dependency and be able to resolve it this way.
The following should do what you intended, and please note how I'm using constructor injection instead of having 2 additional methods in the module.
@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)
Please note that using a Provider<T>
is the cheapest way to resolve a cyclic dependency that I know of, but it might not be suited for every situation.
Upvotes: 5