I'm using in my app hilt for di. I have a BasePresenter for a custom usage which takes as a parameter a List
abstract class BasePresenter(private val rules :MutableList<Rule>){...}
All of the concrete implementation Presenters should extend this one and provide the list like so
class FirstPresenter(rules: MutableList<Rule>) :BasePresenter<IrisView> (rules) {...}
class SecondPresenter(rules: MutableList<Rule>) :BasePresenter<IrisView> (rules) {...}
and each respective module is like so
@Module
@InstallIn(ActivityComponent::class)
object FirstModule {
@Provides
@ActivityScoped
fun provideFirstPresenter(rules: MutableList<Rule>) = FirstPresenter(rules)
@Provides
@ActivityScoped
fun provideRules(): MutableList<Rule> {
val rules = mutableListOf<Rule>()
rules.add(SpecificRule())
return rules
}
This works as expected, however when I try to add a second module for a different usecase like so
@Module
@InstallIn(ActivityComponent::class)
object SecondModule {
@Provides
@ActivityScoped
fun provideSecondPresenter(rules: MutableList<Rule>) = SecondPresenter(rules)
@Provides
@ActivityScoped
fun provideRules(): MutableList<Rule> {
val rules = mutableListOf<Rule>()
rules.add(OtherSpecificRule())
return rules
}
Hilt breaks because It seems that these two module have a different @provides method for MutableList of rules. As I understand this happens because these two Modules exist in the same Scope ( for all Activities, as they are InstalledIn Activity component). So how Can I isolate those two Modules? In Dagger I assigned modules to components which were specific to the corresponding Feature, is that thing possible in Hilt, or should I address this in a different way?
Because Hilt returns the same type MutableList<Rule>
in the same scope, I feel like Hilt is confusing which one to implement, because if a module provides something, it can be injected in a different module that is in equal scope. So, you can actually inject the returned list from fun provideRules()
in the FirstModule
and in the SecondModule
, while providing the first or second presenter. That is why Hilt is generating errors, because it is not determined which one to implement.
If you want different objects, you can use the @Named
annotation and pass the parameter to the function that you target. The code will turn into something like this:
First module:
@Module
@InstallIn(ActivityComponent::class)
object FirstModule {
@Provides
@ActivityScoped
fun provideFirstPresenter(@Named("firstPresenterRules") rules: MutableList<Rule>)
= FirstPresenter(rules)
@Provides
@ActivityScoped
@Named("firstPresenterRules")
fun provideRules(): MutableList<Rule> {
val rules = mutableListOf<Rule>()
rules.add(SpecificRule())
return rules
}
Second module:
@Module
@InstallIn(ActivityComponent::class)
object SecondModule {
@Provides
@ActivityScoped
fun provideSecondPresenter(@Named("secondPresenterRules") rules: MutableList<Rule>)
= SecondPresenter(rules)
@Provides
@ActivityScoped
@Named("secondPresenterRules")
fun provideRules(): MutableList<Rule> {
val rules = mutableListOf<Rule>()
rules.add(OtherSpecificRule())
return rules
}
Using the @Named
annotation with different names allows you to have methods that return the same type, and also provide different ones as you desire.