用 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

SettingsModuleViewModelFactoryModule 因为这就是我在我的 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>)