如果没有 @Provides-annotated 方法,则无法提供,组件中存在具有匹配键的绑定
cannot be provided without an @Provides-annotated method, A binding with matching key exists in component
我正在尝试在种子项目中添加 dagger2 以学习目的(我不是专家),但我遇到了同样的问题:
e: /Users/foca/projects/personalProjects/bar-droid-application/bar-droid/app/build/tmp/kapt3/stubs/debug/com/bar/bar_droid/di/AppComponent.java:8: error: [Dagger/MissingBinding] com.bar.bar_droid.domain.repository.RegisterRepository cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector {
^
A binding with matching key exists in component: com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideRoleSelectorFragmentFactory.RoleSelectionFragmentSubcomponent
com.bar.bar_droid.domain.repository.RegisterRepository is injected at
com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase(registerRepository, …)
com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase is injected at
com.bar.bar_droid.ui.accessflow.roleselector_fragment.viewmodel.RoleSelectionViewModel(…, userRegistrationUseCase)
com.bar.bar_droid.ui.accessflow.roleselector_fragment.viewmodel.RoleSelectionViewModel is injected at
com.bar.bar_droid.ui.di.ViewModelModule.provideRoleSelectionViewModel(roleSelectionViewModel)
java.util.Map,javax.inject.Provider> is injected at
com.bar.bar_droid.utils.mvvm.ViewModelFactory(creators)
com.bar.bar_droid.utils.mvvm.ViewModelFactory is injected at
com.bar.bar_droid.ui.accessflow.loginselector_fragment.LoginFragment.viewModelFactory
com.bar.bar_droid.ui.accessflow.loginselector_fragment.LoginFragment is injected at
dagger.android.AndroidInjector.inject(T) [com.bar.bar_droid.di.AppComponent → com.bar.bar_droid.di.ActivityBuilderModule_BindAccessActivity.AccessActivitySubcomponent → com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideLoginSelectorFragmentFactory.LoginFragmentSubcomponent]
It is also requested at:
com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase(registerRepository, …)
The following other entry points also depend on it:
dagger.android.AndroidInjector.inject(T) [com.bar.bar_droid.di.AppComponent → com.bar.bar_droid.di.ActivityBuilderModule_BindAccessActivity.AccessActivitySubcomponent → com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideMailPasswordFragmentFactory.MailPasswordSignUpFragmentSubcomponent]
dagger.android.AndroidInjector.inject(T) [com.bar.bar_droid.di.AppComponent → com.bar.bar_droid.di.ActivityBuilderModule_BindMainActivity.MainActivitySubcomponent → com.bar.bar_droid.ui.mainflow.di.MainFlowProvider_ProvideMenuFragmentFactory.MenuFragmentSubcomponent]
这是我的代码:
申请:
class MainApplication : Application(), HasAndroidInjector {
@Inject lateinit var androidInjector : DispatchingAndroidInjector<Any>
override fun onCreate() {
super.onCreate()
// Starts Dagger
DaggerAppComponent.builder()
.application(this)
.build()
.inject(this)
}
override fun androidInjector(): AndroidInjector<Any> = androidInjector
}
匕首组件:
@Singleton
@Component(
modules = [AndroidSupportInjectionModule::class,
ApplicationModule::class,
RoomDatabaseModule::class,
FirebaseModule::class,
GoogleModule::class,
ActivityBuilderModule::class]
)
interface AppComponent : AndroidInjector<MainApplication> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(app: Application): Builder
fun build(): AppComponent
}
}
ActivityBuilderModule:
@Module
abstract class ActivityBuilderModule {
@PerActivity
@ContributesAndroidInjector(modules = [AccessScreenProvider::class, AccessScreenDependencyProvider::class])
abstract fun bindAccessActivity(): AccessActivity
@PerActivity
@ContributesAndroidInjector(modules = [MainFlowProvider::class])
abstract fun bindMainActivity(): MainActivity
}
AccessActivity 的片段:
@Module
abstract class AccessScreenProvider {
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class, LoginSelectorProvider::class])
abstract fun provideLoginSelectorFragmentFactory(): LoginFragment
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class])
abstract fun provideMailPasswordFragmentFactory(): MailPasswordSignUpFragment
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class, RoleSelectionProvider::class])
abstract fun provideRoleSelectorFragmentFactory(): RoleSelectionFragment
}
ViewModelModule:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
@Module
abstract class ViewModelModule {
@Binds
abstract fun provideViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@PerFragment
@IntoMap
@ViewModelKey(LoginViewModel::class)
abstract fun provideLoginViewModel(loginViewModel: LoginViewModel): ViewModel
@Binds
@PerFragment
@IntoMap
@ViewModelKey(MailPasswordSignUpViewModel::class)
abstract fun provideMailPasswordSighUpViewModel(mailPasswordSignUpViewModel: MailPasswordSignUpViewModel): ViewModel
@Binds
@PerFragment
@IntoMap
@ViewModelKey(RoleSelectionViewModel::class)
abstract fun provideRoleSelectionViewModel(roleSelectionViewModel: RoleSelectionViewModel): ViewModel
}
最后是 RoleSelectionProvide:
@Module
class RoleSelectionProvider {
@Provides
@PerFragment
fun provideRealAuthDataSource(fireBaseAuth: FirebaseAuth): UserAuthDataSource = RealUserAuthDataSource(fireBaseAuth)
@Provides
@PerFragment
fun provideRegisterRepository(realUserAuthDataSource: RealUserAuthDataSource, userProfileDao: UserProfileDao): RegisterRepository {
return RegisterRepositoryImpl(realUserAuthDataSource, userProfileDao)
}
}
我注入 RegisterRepositoryImpl 的唯一地方是 UserRegistrationUseCase,我不知道我在做什么做错了。
你在两个地方使用它很奇怪:ViewModelModule。这很可能是问题和重复键错误。 "A binding with matching key exists in component:"
此外,在 provideMailPasswordFragmentFactory 中,您仅传递 ViewModelModule,但在
provideRoleSelectorFragmentFactory 您正在传递 ViewModelModule 和 RoleSelectionProvider。在第一种情况下,您缺少提供 Repository 的 RoleSelectionProvider 提供的依赖项。
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class])
abstract fun provideMailPasswordFragmentFactory(): MailPasswordSignUpFragment
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class, RoleSelectionProvider::class])
abstract fun provideRoleSelectorFragmentFactory(): RoleSelectionFragment
我正在尝试在种子项目中添加 dagger2 以学习目的(我不是专家),但我遇到了同样的问题:
e: /Users/foca/projects/personalProjects/bar-droid-application/bar-droid/app/build/tmp/kapt3/stubs/debug/com/bar/bar_droid/di/AppComponent.java:8: error: [Dagger/MissingBinding] com.bar.bar_droid.domain.repository.RegisterRepository cannot be provided without an @Provides-annotated method. public abstract interface AppComponent extends dagger.android.AndroidInjector { ^ A binding with matching key exists in component: com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideRoleSelectorFragmentFactory.RoleSelectionFragmentSubcomponent com.bar.bar_droid.domain.repository.RegisterRepository is injected at com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase(registerRepository, …) com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase is injected at com.bar.bar_droid.ui.accessflow.roleselector_fragment.viewmodel.RoleSelectionViewModel(…, userRegistrationUseCase) com.bar.bar_droid.ui.accessflow.roleselector_fragment.viewmodel.RoleSelectionViewModel is injected at com.bar.bar_droid.ui.di.ViewModelModule.provideRoleSelectionViewModel(roleSelectionViewModel) java.util.Map,javax.inject.Provider> is injected at com.bar.bar_droid.utils.mvvm.ViewModelFactory(creators) com.bar.bar_droid.utils.mvvm.ViewModelFactory is injected at com.bar.bar_droid.ui.accessflow.loginselector_fragment.LoginFragment.viewModelFactory com.bar.bar_droid.ui.accessflow.loginselector_fragment.LoginFragment is injected at dagger.android.AndroidInjector.inject(T) [com.bar.bar_droid.di.AppComponent → com.bar.bar_droid.di.ActivityBuilderModule_BindAccessActivity.AccessActivitySubcomponent → com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideLoginSelectorFragmentFactory.LoginFragmentSubcomponent] It is also requested at: com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase(registerRepository, …) The following other entry points also depend on it: dagger.android.AndroidInjector.inject(T) [com.bar.bar_droid.di.AppComponent → com.bar.bar_droid.di.ActivityBuilderModule_BindAccessActivity.AccessActivitySubcomponent → com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideMailPasswordFragmentFactory.MailPasswordSignUpFragmentSubcomponent] dagger.android.AndroidInjector.inject(T) [com.bar.bar_droid.di.AppComponent → com.bar.bar_droid.di.ActivityBuilderModule_BindMainActivity.MainActivitySubcomponent → com.bar.bar_droid.ui.mainflow.di.MainFlowProvider_ProvideMenuFragmentFactory.MenuFragmentSubcomponent]
这是我的代码:
申请:
class MainApplication : Application(), HasAndroidInjector {
@Inject lateinit var androidInjector : DispatchingAndroidInjector<Any>
override fun onCreate() {
super.onCreate()
// Starts Dagger
DaggerAppComponent.builder()
.application(this)
.build()
.inject(this)
}
override fun androidInjector(): AndroidInjector<Any> = androidInjector
}
匕首组件:
@Singleton
@Component(
modules = [AndroidSupportInjectionModule::class,
ApplicationModule::class,
RoomDatabaseModule::class,
FirebaseModule::class,
GoogleModule::class,
ActivityBuilderModule::class]
)
interface AppComponent : AndroidInjector<MainApplication> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(app: Application): Builder
fun build(): AppComponent
}
}
ActivityBuilderModule:
@Module
abstract class ActivityBuilderModule {
@PerActivity
@ContributesAndroidInjector(modules = [AccessScreenProvider::class, AccessScreenDependencyProvider::class])
abstract fun bindAccessActivity(): AccessActivity
@PerActivity
@ContributesAndroidInjector(modules = [MainFlowProvider::class])
abstract fun bindMainActivity(): MainActivity
}
AccessActivity 的片段:
@Module
abstract class AccessScreenProvider {
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class, LoginSelectorProvider::class])
abstract fun provideLoginSelectorFragmentFactory(): LoginFragment
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class])
abstract fun provideMailPasswordFragmentFactory(): MailPasswordSignUpFragment
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class, RoleSelectionProvider::class])
abstract fun provideRoleSelectorFragmentFactory(): RoleSelectionFragment
}
ViewModelModule:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
@Module
abstract class ViewModelModule {
@Binds
abstract fun provideViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@PerFragment
@IntoMap
@ViewModelKey(LoginViewModel::class)
abstract fun provideLoginViewModel(loginViewModel: LoginViewModel): ViewModel
@Binds
@PerFragment
@IntoMap
@ViewModelKey(MailPasswordSignUpViewModel::class)
abstract fun provideMailPasswordSighUpViewModel(mailPasswordSignUpViewModel: MailPasswordSignUpViewModel): ViewModel
@Binds
@PerFragment
@IntoMap
@ViewModelKey(RoleSelectionViewModel::class)
abstract fun provideRoleSelectionViewModel(roleSelectionViewModel: RoleSelectionViewModel): ViewModel
}
最后是 RoleSelectionProvide:
@Module
class RoleSelectionProvider {
@Provides
@PerFragment
fun provideRealAuthDataSource(fireBaseAuth: FirebaseAuth): UserAuthDataSource = RealUserAuthDataSource(fireBaseAuth)
@Provides
@PerFragment
fun provideRegisterRepository(realUserAuthDataSource: RealUserAuthDataSource, userProfileDao: UserProfileDao): RegisterRepository {
return RegisterRepositoryImpl(realUserAuthDataSource, userProfileDao)
}
}
我注入 RegisterRepositoryImpl 的唯一地方是 UserRegistrationUseCase,我不知道我在做什么做错了。
你在两个地方使用它很奇怪:ViewModelModule。这很可能是问题和重复键错误。 "A binding with matching key exists in component:"
此外,在 provideMailPasswordFragmentFactory 中,您仅传递 ViewModelModule,但在 provideRoleSelectorFragmentFactory 您正在传递 ViewModelModule 和 RoleSelectionProvider。在第一种情况下,您缺少提供 Repository 的 RoleSelectionProvider 提供的依赖项。
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class])
abstract fun provideMailPasswordFragmentFactory(): MailPasswordSignUpFragment
@PerFragment
@ContributesAndroidInjector(modules = [ViewModelModule::class, RoleSelectionProvider::class])
abstract fun provideRoleSelectorFragmentFactory(): RoleSelectionFragment