用 Dagger2 注入 ViewModel
Inject ViewModel with Dagger2
我正在使用 Dagger2 和新的架构组件构建一个 Android 应用程序。我尝试按照本教程使 ViewModels 可注入:https://blog.kotlin-academy.com/understanding-dagger-2-multibindings-viewmodel-8418eb372848
当我 运行 我的代码时,出现以下错误:
[AndroidInjector.inject(T) Map<Class<? extends ViewModel>, Provider<ViewModel>> cannot be provided without an @Provides-annotated method.
我的代码如下所示:
@Singleton
class ViewModelFactory @Inject constructor(
private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val creator = creators[modelClass]
?: creators.asIterable().firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
?: throw IllegalArgumentException("Unknown model class $modelClass")
return creator.get() as T
}
}
@Module
abstract class ViewModelFactoryModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
@MapKey
@Target(FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER)
annotation class ViewModelKey(val value: KClass<out ViewModel>)
我的模块也包含在 AppComponent 中:
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
ViewModelFactoryModule::class // ...
])
interface AppComponent : AndroidInjector<BaseApplication>
class BaseApplication : DaggerApplication(), HasActivityInjector {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder().appModule(AppModule(this)).build()
}
我尝试注入的 ViewModel 在模块中声明如下:
@Module
abstract class SettingsModule {
@Binds
@IntoMap
@ViewModelKey(SettingsViewModel::class)
abstract fun bindSettingsViewModel(model: SettingsViewModel): ViewModel
}
有人知道问题出在哪里吗?
很难指出 Dagger 的确切问题。尝试移动
@Binds
@IntoMap
@ViewModelKey(SettingsViewModel::class)
abstract fun bindSettingsViewModel(model: SettingsViewModel): ViewModel
从 SettingsModule
到 ViewModelFactoryModule
因为这就是我在我的 code-base 中所做的并且它正在工作。
@Module
abstract class ViewModelFactoryModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory):
ViewModelProvider.Factory
}
或
尝试将您的 ViewModelKey
更改为:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
我正在使用 Dagger2 和新的架构组件构建一个 Android 应用程序。我尝试按照本教程使 ViewModels 可注入:https://blog.kotlin-academy.com/understanding-dagger-2-multibindings-viewmodel-8418eb372848
当我 运行 我的代码时,出现以下错误:
[AndroidInjector.inject(T) Map<Class<? extends ViewModel>, Provider<ViewModel>> cannot be provided without an @Provides-annotated method.
我的代码如下所示:
@Singleton
class ViewModelFactory @Inject constructor(
private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val creator = creators[modelClass]
?: creators.asIterable().firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
?: throw IllegalArgumentException("Unknown model class $modelClass")
return creator.get() as T
}
}
@Module
abstract class ViewModelFactoryModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
@MapKey
@Target(FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER)
annotation class ViewModelKey(val value: KClass<out ViewModel>)
我的模块也包含在 AppComponent 中:
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
ViewModelFactoryModule::class // ...
])
interface AppComponent : AndroidInjector<BaseApplication>
class BaseApplication : DaggerApplication(), HasActivityInjector {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder().appModule(AppModule(this)).build()
}
我尝试注入的 ViewModel 在模块中声明如下:
@Module
abstract class SettingsModule {
@Binds
@IntoMap
@ViewModelKey(SettingsViewModel::class)
abstract fun bindSettingsViewModel(model: SettingsViewModel): ViewModel
}
有人知道问题出在哪里吗?
很难指出 Dagger 的确切问题。尝试移动
@Binds
@IntoMap
@ViewModelKey(SettingsViewModel::class)
abstract fun bindSettingsViewModel(model: SettingsViewModel): ViewModel
从 SettingsModule
到 ViewModelFactoryModule
因为这就是我在我的 code-base 中所做的并且它正在工作。
@Module
abstract class ViewModelFactoryModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory):
ViewModelProvider.Factory
}
或
尝试将您的 ViewModelKey
更改为:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)