Привязка К Карте С Типом KClass
Я пытаюсь связать подклассы ViewModel
в карту по их KClass
типам:
@Module abstract class ViewModelModule {
@Binds @IntoMap @ViewModelKey(MyViewModel::class)
abstract fun bindsMyViewModel(viewModel: MyViewModel): ViewModel
@Binds abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
Но я получаю ошибку компилятора Dagger:
e: ~/Example/app/build/tmp/kapt3/stubs/debug/com/example/app/injection/AppComponent.java:5: error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
e:
e: public abstract interface AppComponent {
e: ^
e: java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at
e: com.example.app.ui.ViewModelFactory.<init>(creators)
e: com.example.app.ui.ViewModelFactory is injected at
e: com.example.app.injection.ViewModelModule.bindViewModelFactory(p0)
e: android.arch.lifecycle.ViewModelProvider.Factory is injected at
e: com.example.app.ui.MyFragment.setViewModelFactory(p0)
e: com.example.app.ui.MyFragment is injected at
e: dagger.android.AndroidInjector.inject(arg0)
Вышеупомянутый ViewModelModule
включен в мой AppModule
, который является модулем в моем AppComponent
. Так что Кинжал должен быть в состоянии обеспечить Map<KClass<out ViewModel>, Provider<ViewModel>>
, требуемое моим ViewModelFactory
, но я не могу понять, почему он разбивается.
Я также попытался переключить класс аннотаций ViewModelKey
на Java, взяв Class
в качестве параметра конструктора вместо KClass
. Затем модифицировал мой ViewModelFactory
, чтобы зависеть от Map<Class<out ViewModel>, Provider<ViewModel>>
, но произошла та же ошибка.
1 ответ:
При использовании
KClass
в аннотации он фактически компилируется в JavaClass
. Но на самом деле проблема заключается в подстановочном знаке вjava.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>>
, который генерирует компилятор Kotlin.Предполагая, что
@ViewModelKey
определяется как@MapKey annotation class ViewModelKey(val value: KClass<out ViewModel>)
Вам нужно будет определить место инъекции как
Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
Использование
@JvmSuppressWildcards
не позволит компилятору создавать подстановочные знаки.Я на самом деле не знаю, почему подстановочные знаки не поддерживаются компилятором Dagger. Вы можете увидеть аналогичную проблему здесь: Кинжал 2: Как ввести Map , провайдер удлиняет Фу>>