Dagger/MissingBinding Repository cannot be provided without an @Provides-annotated method

Viewed 926

I'm trying to setup a multi-module Android app using Hilt, but after setting up everything I get the following error:

D:\Projetos\historico-de-notificacoes\app\build\generated\source\kapt\debug\br\com\firstsoft\historiconotificacoes\src\NotificationHistoryApplication_HiltComponents.java:124: error: [Dagger/MissingBinding] br.com.firstsoft.historiconotificacoes.domain.src.repository.NotificationRepository cannot be provided without an @Provides-annotated method.
  public abstract static class SingletonC implements NotificationHistoryApplication_GeneratedInjector,
                         ^
      br.com.firstsoft.historiconotificacoes.domain.src.repository.NotificationRepository is injected at
          br.com.firstsoft.historiconotificacoes.domain.src.usecase.notification.GetRecentNotificationsUseCaseImpl(notificationRepository)
      br.com.firstsoft.historiconotificacoes.domain.src.usecase.notification.GetRecentNotificationsUseCaseImpl is injected at
          br.com.firstsoft.historiconotificacoes.domain.src.usecase.UseCaseModule.bindsGetRecentNotificationsUseCase(arg0)
      br.com.firstsoft.historiconotificacoes.domain.src.usecase.notification.GetRecentNotificationsUseCase is injected at
          br.com.firstsoft.historiconotificacoes.src.notifications.recent.RecentViewModel(getRecentNotificationsUseCase)
      br.com.firstsoft.historiconotificacoes.src.notifications.recent.RecentViewModel is injected at
          br.com.firstsoft.historiconotificacoes.src.notifications.recent.RecentViewModel_HiltModules.BindsModule.binds(vm)
      @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
          dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [br.com.firstsoft.historiconotificacoes.src.NotificationHistoryApplication_HiltComponents.SingletonC ? br.com.firstsoft.historiconotificacoes.src.NotificationHistoryApplication_HiltComponents.ActivityRetainedC ? br.com.firstsoft.historiconotificacoes.src.NotificationHistoryApplication_HiltComponents.ViewModelC]

I have my code setup like:

:domain

plugins {
    id("com.android.library")
    id("kotlin-android")
    id("kotlin-kapt")
    id("dagger.hilt.android.plugin")
}

dependencies {
    implementation(Libs.Kotlin.stdLib)

    implementation(Libs.Coroutines.core)

    implementation(Libs.Paging.runtime)

    implementation(Libs.Hilt.core)
    kapt(Libs.Hilt.compiler)
}

:data

plugins {
    id("com.android.library")
    id("kotlin-android")
    id("kotlin-kapt")
    id("dagger.hilt.android.plugin")
}

dependencies {
    implementation(project(":domain"))

    implementation(Libs.Kotlin.stdLib)

    implementation(Libs.Room.runtime)
    implementation(Libs.Room.ktx)
    kapt(Libs.Room.compiler)

    implementation(Libs.Paging.runtime)

    implementation(Libs.Hilt.core)
    kapt(Libs.Hilt.compiler)

    implementation(Libs.Android.annotation)

    implementation(Libs.Util.gson)
}

:app

plugins {
    id("com.android.application")
    id("kotlin-android")
    id("kotlin-kapt")
    id("dagger.hilt.android.plugin")
}

dependencies {
    implementation(project(":domain"))

    implementation(Libs.Kotlin.stdLib)

    ...

    implementation(Libs.Hilt.core)
    kapt(Libs.Hilt.compiler)
}

Inside :domain I have:

interface NotificationRepository {}

Inside :data I have:

class NotificationRepositoryImpl @Inject constructor(
    private val notificationDao: NotificationDao
) : NotificationRepository


@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {

    @Binds
    abstract fun bindsNotificationRepository(impl: NotificationRepositoryImpl): NotificationRepository
}

I don't where I messed up but shouldn't this be working? If not, what am I doing wrong?

2 Answers

After looking at some examples and comments of this question. I solve this problem just by implementing the data module and the domain module into my app module :)

But this is not what I was thinking of. So just implement modules in the app module in the module app in build gradle file add this line

implementation project(":data")

For example, if you have 3 modules app, domain, and data in your app and you should implement all the modules in your app build.gradle file.

The trick here was to implement :data inside :app.

In this specific scenario where we have only these 3 modules, :app, :data and :domain, there has to be a module that aggregates the others, which is this case is the :app.

Related