I'm using Dagger 2
Android injector to inject my Activities
and Fragments
.
I have a generic RecyclerView
Adapter and keeping ViewHolderFactories
and Binders
in a Map
.
Here's my adapter:
@Module
class CorePresentationModule {
@Provides
fun provideDisplayItemComperator(): DisplayItemComperator = DefaultDisplayItemComperator()
@Module
companion object {
@JvmStatic
@Provides
fun provideRecyclerAdapter(
itemComparator: DisplayItemComperator,
factoryMap: Map<Int, @JvmSuppressWildcards ViewHolderFactory>,
binderMap: Map<Int, @JvmSuppressWildcards ViewHolderBinder>,
androidPreconditions: AndroidPreconditions
): RecyclerViewAdapter {
return RecyclerViewAdapter(
itemComperator = itemComparator,
viewHolderFactoryMap = factoryMap,
viewBinderFactoryMap = binderMap,
androidPreconditions = androidPreconditions
)
}
}
}
I crate a presentation module for my Fragment like the following:
@Module
abstract class MessagesPresentationModule {
@Binds
@IntoMap
@IntKey(MESSAGE)
internal abstract fun provideMessagesViewModelFactory(factory: MessagesViewHolder.MessageViewHolderFactory): ViewHolderFactory
@Binds
@IntoMap
@IntKey(MESSAGE)
internal abstract fun provideMessagesViewHolderBinder(binder: MessagesViewHolder.MessagesViewHolderBinder): ViewHolderBinder
}
In another fragment i inject my adapter again and create another module for my screen:
@Module
abstract class LinksPresentationModule {
@Binds
@IntoMap
@IntKey(LINK)
internal abstract fun provideLinksViewModelFactory(factory: LinksViewHolder.LinksViewHolderFactory): ViewHolderFactory
@Binds
@IntoMap
@IntKey(LINK)
internal abstract fun provideLinksViewHolderBinder(binder: LinksViewHolder.LinksViewHolderBinder): ViewHolderBinder
}
When MESSAGE
and LINK
is 0 i get a compile error
The same map key is bound more than once for
ViewHolderFactory
What's is the best solution to get avoid this execpt putting all IntKeys
in a constants class with ordered and incremented?
Thanks.
After long research in my code, I found the missing point. I provide my presentation modules
in Application component
so it generates only one Map for each type and gets this duplicate MapKey
error.
The same map key is bound more than once for ViewHolderFactory
I found this useful article in Medium. I realised that created my modules for Application Scope
. So SubComponents
for my presentation modules does not get generated and Dagger
creates only one Map for factory classes. I redesigned my Dagger
implementation for my presentation modules to keep them FragmentScoped
as it should be like the following code.
@Module
abstract class MessagesFragmentModule {
@FragmentScope
@ContributesAndroidInjector(modules = [MessagesPresentationModule::class]
abstract fun contributeMessagesFragment(): MessagesFragment
}
@Module
abstract class LinksFragmentModule {
@FragmentScope
@ContributesAndroidInjector(modules = [LinksPresentationModule::class]
abstract fun provideLinksFragment(): LinksFragment
}
And here's ActivityModule
@Module
internal abstract class ActivityModule {
@ContributesAndroidInjector(
modules = [MessagesFragmentModule::class,
LinksFragmentModule::class]
)
@ActivityScope
abstract fun provideMainActivityContributor(): MainActivity
}