Я использую известный шаблон 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
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что при внедренииЗавалить фабрику в Кинжал Активности не удается, потому что поставщики объектов для Моделей Представления, которые я не собираюсь использовать, не всегда доступны. Это не потому, что модули, содержащие провайдеров, не были добавлены.
Например, у меня есть активность входа в систему и операция регистрации, и вот как я добавляю для них подкомпоненты:
@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 extends dagger.android.AndroidInjector {^ В компоненте существует привязка с соответствующим ключом: com.package.my.di.ActivityInjectorsModule_LoginActivityInjector $ app_prodDebug.LoginActivitySubcomponent com.package.my.login.domain.LogInAjectpackage.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 (viewModeu.ava). Карта javax.inject.Provider> внедряется в com.package.my.di.ViewModelFactory (создатели) com.package.my.di.ViewModelFactory внедряется в com.package.my.di.ViewModelModule.bindViewModelFactory $ app_prodDebug (factory) 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
, даже если мне не нужно создавать GoogleSignInClient
в SignUpActivity
?