не может быть предоставлен без аннотированного метода @ Provides, в компоненте существует привязка с соответствующим ключом - PullRequest
0 голосов
/ 29 января 2020

Я пытаюсь добавить 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: ошибка: [Dagger / MissingBinding] ком. bar.bar_droid.domain.repository.RegisterRepository не может быть предоставлен без аннотируемого метода @ Provides. publi c абстрактный интерфейс AppComponent расширяет кинжал. android .AndroidInjector {^ Привязка с соответствующим ключом существует в компоненте: com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideRoleSelectorFragmentFactory.RoleSelectionFragmentSubcomponreroid..do.bar.dobar .RegisterRepository внедряется в com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase (registerRepository,…) com.bar.bar_droid.domain.interactor.userregistration.UserRegistrationUseCase внедряется в com.bar.bar_droid.ui.lect_ .viewmodel.RoleSelectionViewModel (…, userRegistrationUseCase) ru , javax.inject.Provider> внедряется в com.bar.bar_droid.utils.mvvm.ViewModelFactory (создатели) com.bar.bar_droid.utils.mvvm.ViewModelFactory is inje cted at com.bar.bar_droid.ui.accessflow.loginselector_fragment.LoginFragment.viewModelFactory com.bar.bar_droid.ui.accessflow.loginselector_fragment.LoginFragment вводится в кинжал. android .AndroidInjector.inject () bar_droid.di.AppComponent → com.bar.bar_droid.di.ActivityBuilderModule_BindAccessActivity.AccessActivitySubcomponent → com.bar.bar_droid.ui.accessflow.di.AccessScreenProvider_ProvideLoginSelector.FragmentFactory.org userregistration.UserRegistrationUseCase (registerRepository,…) Следующие другие точки входа также зависят от него: кинжал. 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] кинжал. 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_ProvideMenuFragment * фабрика * * * 100 * * * 100 * 100: 100 * * * 100: 1006 * 1005] мой факс: 1004 * 1005] мой5-й фин.

Приложение:

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 , Я понятия не имею, что я делаю неправильно.

1 Ответ

0 голосов
/ 30 января 2020

Странно, что вы используете его в двух местах: ViewModelModule. Скорее всего это проблема и ошибки дублирования ключей. «Привязка с соответствующим ключом существует в компоненте:«

Также в provideMailPasswordFragmentFactory вы передаете только ViewModelModule, но в provideRoleSelectorFragmentFactory вы передаете как ViewModelModule, так и RoleSelectionProvider. В первом случае вам не хватает зависимостей, предоставляемых RoleSelectionProvider, который предоставляет репозиторий.

    @PerFragment
    @ContributesAndroidInjector(modules = [ViewModelModule::class])
    abstract fun provideMailPasswordFragmentFactory(): MailPasswordSignUpFragment

    @PerFragment
    @ContributesAndroidInjector(modules = [ViewModelModule::class, RoleSelectionProvider::class])
    abstract fun provideRoleSelectorFragmentFactory(): RoleSelectionFragment
...