【发布时间】:2020-03-06 01:29:06
【问题描述】:
我正在使用著名的 Dagger-ViewModelFactory 模式来为所有活动中的所有 ViewModel 注入工厂。
@ActivityScope
class ViewModelFactory @Inject constructor(
private val creators: MutableMap<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val creator = creators[modelClass] ?: creators.entries.firstOrNull {
modelClass.isAssignableFrom(it.key)
}?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
return creator.get() as T
}
}
我遇到的问题是,当我将工厂注入 Activity Dagger 时失败,因为我不会使用的 ViewModels 对象的提供者并不总是可以访问。不是因为没有添加包含提供程序的模块。
例如,我有一个 LogIn 活动和一个 SignUp 活动,这就是我为它们添加子组件的方式:
@ContributesAndroidInjector(modules = [
ViewModelModule::class,
FirebaseModule::class,
LogInModule::class,
BindLogInModule::class
])
@ActivityScope
internal abstract fun loginActivityInjector(): LoginActivity
@ContributesAndroidInjector(modules = [
ViewModelModule::class,
FirebaseModule::class,
SignUpModule::class,
BindSignUpModule::class
])
@ActivityScope
internal abstract fun signUpActivityInjector(): SignUpActivity
请注意,当我为SignUpActivity 创建子组件时,我没有添加模块LogInModule,因为我不需要该模块中的绑定。
结果是我得到了错误
e: com.package.my.AppComponent.java:8: error: [Dagger/MissingBinding] com.package.my.login.domain.LogInAuthenticator 不能在没有 @Provides 注释的方法的情况下提供。 公共抽象接口 AppComponent 扩展 dagger.android.AndroidInjector { ^ 组件中存在具有匹配键的绑定:com.package.my.di.ActivityInjectorsModule_LoginActivityInjector$app_prodDebug.LoginActivitySubcomponent com.package.my.login.domain.LogInAuthenticator 被注入 com.package.my.login.repository.LoginRepository(logInAuthenticator) com.package.my.login.repository.LoginRepository 被注入 com.package.my.login.domain.LoginUseCase(loginRepository) com.package.my.login.domain.LoginUseCase 被注入 com.package.my.login.presentation.LoginViewModel(loginUseCase) com.package.my.login.presentation.LoginViewModel 注入于 com.package.my.di.ViewModelModule.provideLoginViewModel(viewModel) java.util.Map,javax.inject.Provider> 被注入 com.package.my.di.ViewModelFactory(创作者) com.package.my.di.ViewModelFactory 注入于 com.package.my.di.ViewModelModule.bindViewModelFactory$app_prodDebug(工厂) androidx.lifecycle.ViewModelProvider.Factory 在注入 com.package.my.login.ui.SignUpActivity.viewModelFactory com.package.my.login.ui.SignUpActivity 被注入 dagger.android.AndroidInjector.inject(T) [com.package.my.di.AppComponent → com.package.my.di.ActivityInjectorsModule_SignUpActivityInjector$app_prodDebug.SignUpActivitySubcomponent]
这是因为LogInAuthenticator 是由LogInModule 提供的。
这是否意味着唯一的解决方案是添加LogInModule,即使我真的不需要在SignUpActivity 中创建GoogleSignInClient?
【问题讨论】:
-
请始终包含错误消息的完整“堆栈跟踪”及其周围的代码。我相信问题是由于将
LoginViewModel添加到注册组件而出现的。通常您注册一次ViewModelFactory(例如您的 AppComponent)然后将视图模型绑定添加到您需要它们的组件中,因此只需将登录虚拟机添加到登录组件,将注册虚拟机添加到注册组件等 -
@DavidMedenjak 我没有将
LoginViewModel添加到 SignUp 子组件中。如果我这样做,那么它会起作用,但我不想这样做 -
我没有添加整个错误,因为我认为问题很清楚。解决方案不是。另请注意,我也创建了一次工厂。问题是我需要在所有子组件中添加所有依赖项,而不仅仅是每个特定子组件的必要依赖项。
-
我现在添加了整个错误
标签: android dependency-injection viewmodel dagger-2 dagger