android - español - mvp kotlin dagger
Encuadernación en el mapa con el tipo de clase K (1)
Cuando se usa KClass
en una anotación, en realidad se compila a la Class
de Java. Pero el problema real es el comodín en java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>>
java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>>
java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>>
que está generando el compilador Kotlin.
Suponiendo que @ViewModelKey
se define como
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
Tendrá que definir su sitio de inyección como
Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
El uso de @JvmSuppressWildcards
evitará que el compilador genere comodines.
Realmente no sé por qué los comodines no son compatibles con el compilador Dagger. Puede ver un problema similar aquí: Daga 2: ¿Cómo inyectar el Mapa <Clase <? Extiende Foo>, Proveedor <? extiende Foo >>
Estoy tratando de unir las subclases de ViewModel
en un mapa por sus tipos KClass
:
@Module abstract class ViewModelModule {
@Binds @IntoMap @ViewModelKey(MyViewModel::class)
abstract fun bindsMyViewModel(viewModel: MyViewModel): ViewModel
@Binds abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
Pero estoy recibiendo un error del compilador de 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)
El ViewModelModule
anterior se incluye en mi AppModule
, que es un módulo en mi AppComponent
. Así que Dagger debería poder proporcionar el Map<KClass<out ViewModel>, Provider<ViewModel>>
requerido por mi ViewModelFactory
, pero no puedo entender por qué está fallando.
También intenté cambiar la clase de anotación de ViewModelKey
a Java, tomando una Class
como un parámetro de constructor en lugar de una KClass
. Luego modifiqué mi ViewModelFactory
para depender de un Map<Class<out ViewModel>, Provider<ViewModel>>
, pero ocurrió el mismo error.