Dagger2, ViewModelProvider.Factory:использует более одного типа аннотации @MapKey - PullRequest
0 голосов
/ 04 июня 2019

Я занимаюсь разработкой библиотеки, которая определяет некоторые фрагменты. Теперь библиотеку необходимо интегрировать в уже существующее приложение.

В обоих проектах используется Android Dagger2 и Dagger2, и я могу изменять источники как библиотеки, так и приложения. Они оба используют MVVM и используют этот способ внедрения экземпляров ViewModel их фрагментов.

В библиотеке у меня есть:

Связующий модуль:

@Module
abstract class LibViewModelBindingModule {
    @Binds
    internal abstract fun bindLibViewModelFactory(factory: LibraryViewModelFactory): ViewModelProvider.Factory
}

LibraryViewModelFactory

class LibraryViewModelFactory
@Inject constructor(private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>) :
    ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}

Приложение имеет в основном копии из приведенных выше классов:

Модуль привязки приложения:

@Module
abstract class AppViewModelBindingModule {
    @Binds
    internal abstract fun bindAppViewModelFactory(factory: AppViewModelFactory): ViewModelProvider.Factory
}

AppViewModelFactory

class AppViewModelFactory
@Inject constructor(private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>) :
    ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}

После интеграции библиотеки в приложение (как .aar) и после добавления модулей Dagger2, определенных в библиотеке, в граф зависимостей приложения Dagger2, при попытке построения Dagger останавливает сборку из-за следующей ошибки:

e: <long-path>/MainAppComponent.java:37: error: [Dagger/MapKeys] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> uses more than one @MapKey annotation type
public interface MainAppComponent {
                 ^

Я знаю, что теоретически могу удалить AppViewModelFactory и просто использовать LibraryViewModelFactory в приложении, но это больше работает и выглядит как обходной путь. Я также не хочу делать это для всех приложений, в которые я буду интегрировать свою библиотеку.

Помимо прочего, я также пытался использовать классификатор для карты, полученной LibraryViewModelFactory, но это не помогло:

class LibraryViewModelFactory
@Inject constructor(@LibraryViewModelsMap private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>) :
    ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}

Есть идеи? Такое ощущение, что я упускаю что-то очень очевидное

...