Dagger 2 A binding with matching key exists in component

I’ve seen that this is a problem that has already been asked around here, but I can’t seem to solve it in my code after going around several times. I am trying to implement Room with Dagger 2 in my application, I have created the necessary Module where I create the references to the database and the Dao class.

The problem is when I compile my project, which gives me this error and I have tried many things and I can not solve it, I pass part of the code to see if you can help me:

My class AppComponent:

@Singleton
@Component(
    modules = [
        AndroidInjectionModule::class,
        AppModule::class,
        LoginModule::class,
        LoginBuilder::class,
        DatabaseModule::class,
        DashboardBuilder::class,
        ActivityBuilder::class,
        HomeBuilder::class,
        HomeModule::class,
        ContactBuilder::class
    ]
)
interface AppComponent {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder
        fun build(): AppComponent
    }

    fun inject(app: App)
}

My AppComponent autogenerate for Dagger 2:

@kotlin.Metadata(mv = {1, 1, 16}, bv = {1, 0, 3}, k = 1, d1 = {"u0000u0018nu0002u0018u0002nu0002u0010u0000nu0000nu0002u0010u0002nu0000nu0002u0018u0002nu0002bu0002bgu0018u00002u00020u0001:u0001u0006Ju0010u0010u0002u001au00020u00032u0006u0010u0004u001au00020u0005H&u00a8u0006u0007"}, d2 = {"Lcom/ludiras/ameisin/dagger/component/AppComponent;", "", "inject", "", "app", "Lcom/ludiras/ameisin
/App;", "Builder", "app_debug"})
@dagger.Component(modules = {dagger.android.AndroidInjectionModule.class, com.ludiras.ameisin.dagger.modules.AppModule.class, 
com.ludiras.ameisin.dagger.modules.LoginModule.class, com.ludiras.ameisin.dagger.modules.LoginBuilder.class, com.ludiras.ameisin.dagger.modules.DatabaseModule.class, com.ludiras.ameisin.dagger.modules.DashboardBuilder.class, com.ludiras.ameisin.dagger.modules.ActivityBuilder.class, com.ludiras.ameisin.dagger.modules.HomeBuilder.class, com.ludiras.ameisin.dagger.modules.HomeModule.class, com.ludiras.ameisin.dagger.modules.ContactBuilder.class})
@javax.inject.Singleton()
public abstract interface AppComponent {
    
    public abstract void inject(@org.jetbrains.annotations.NotNull()
    com.ludiras.ameisin.App app);
    
    @kotlin.Metadata(mv = {1, 1, 16}, bv = {1, 0, 3}, k = 1, d1 = {"u0000u0016nu0002u0018u0002nu0002u0010u0000nu0000nu0002u0018u0002nu0000nu0002u0018u0002nu0000bgu0018u00002u00020u0001Ju0010u0010u0002u001au00020u00002u0006u0010u0002u001au00020u0003H'Jbu0010u0004u001au00020u0005H&u00a8u0006u0006"}, d2 = {"Lcom/ludiras/ameisin/dagger/component/AppComponent$Builder;", "", "application", "Landroid/app/Application;", "build", "Lcom/ludiras/ameisin/dagger/component/AppComponent;", "app_debug"})
    @dagger.Component.Builder()
    public static abstract interface Builder {
        
        @org.jetbrains.annotations.NotNull()
        @dagger.BindsInstance()
        public abstract com.ludiras.ameisin.dagger.component.AppComponent.Builder application(@org.jetbrains.annotations.NotNull()
        android.app.Application application);
        
        @org.jetbrains.annotations.NotNull()
        public abstract com.ludiras.ameisin.dagger.component.AppComponent build();
    }
}

My error from console:

AppComponent.java:8: error: [Dagger/MissingBinding] com.ludiras.ameisin.App cannot be provided without an @Inject constructor or an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
public abstract interface AppComponent {
                ^
  A binding with matching key exists in component: com.ludiras.ameisin.dagger.component.AppComponent
      com.ludiras.ameisin.App is injected at
          com.ludiras.ameisin.dagger.modules.AppModule.provideApplication(app)
      android.content.Context is injected at
          com.ludiras.ameisin.dagger.modules.DatabaseModule.provideUserDataBase(context)
      com.ludiras.ameisin.database.UsersDatabase is injected at
          com.ludiras.ameisin.dagger.modules.DatabaseModule.provideUserDao(usersDatabase)
      com.ludiras.ameisin.database.dao.UserDao is injected at
          com.ludiras.ameisin.dagger.modules.LoginModule.provideRegisterRepository(�, userDao)
      com.ludiras.ameisin.ui.login.repository.RegisterRepository is injected at
          com.ludiras.ameisin.ui.login.viewmodel.LoginViewModel(registerRepository, �)
      javax.inject.Provider<com.ludiras.ameisin.ui.login.viewmodel.LoginViewModel> is injected at
          com.ludiras.ameisin.dagger.modules.ViewModelFactory(viewModelProvider)
      com.ludiras.ameisin.dagger.modules.ViewModelFactory<com.ludiras.ameisin.ui.login.viewmodel.LoginViewModel> is injected at
          com.ludiras.ameisin.ui.login.view.LoginFragment.viewModelFactory
      com.ludiras.ameisin.ui.login.view.LoginFragment is injected at
          dagger.android.AndroidInjector.inject(T) [com.ludiras.ameisin.dagger.component.AppComponent ? com.ludiras.ameisin.dagger.modules.LoginBuilder_BindLoginFragment$app_debug.LoginFragmentSubcomponent][WARN] Incremental annotation processing requested, but support is disabled because the following processors are not incremental: androidx.room.RoomProcessor (DYNAMIC).

My LoginModule class:

@Module
class LoginModule {

    @Provides
    @Singleton
    fun provideFirebaseAuth(): FirebaseAuth = FirebaseAuth.getInstance()

    @Provides
    @Singleton
    fun provideFirebaseFirestore(): FirebaseFirestore = FirebaseFirestore.getInstance()

    @Provides
    @Singleton
    fun provideLoginRepository(firebaseAuth: FirebaseAuth): LoginRepository =
        LoginRepository(firebaseAuth)

    @Provides
    @Singleton
    fun provideRegisterRepository(
        firebaseAuth: FirebaseAuth,
        firebaseFirestore: FirebaseFirestore,
        userDao: UserDao
    ): RegisterRepository = RegisterRepository(userDao, firebaseFirestore, firebaseAuth)
}

And my LoginBuilder class:

@Module
abstract class LoginBuilder {

    @ContributesAndroidInjector()
    internal abstract fun bindLoginFragment(): LoginFragment
}

Answer

Modify your AppComponent as follows.

interface AppComponent {

@Component.Builder
interface Builder {

    @BindsInstance
    fun application(application: App): Builder
    fun build(): AppComponent
}
fun inject(app: App)
}

Its failing because you have bounded a dependency it cannot be accessed from sub component where it needed for injection. i.e dependency of App .

Leave a Reply

Your email address will not be published. Required fields are marked *