Search code examples
androiddependency-injectiondagger-hilt

I can't inject Dao to a Repository Class, with HILT, in Android


i follow this tutorial Room Dependency Injection - MVVM To-Do List App with Flow and Architecture Components #4

Now I want to convert, a hole app that I have with Room, to this Clean Architecture. In the tutorial Florian uses DI, to inject TaskDao into TaskViewModel, but I have a Repositories clases.

So I get to a point where the app is build without errors.

and this is my Repository:

    class AnioRepository constructor(
        private val agrotrackerApi: AgrotrackerApi
    ) {
    val TAG = "AnioRepository"
    //val anioDao: AnioDao

    fun downloadAnios(): AniosResponse? {
        GlobalScope.launch(Dispatchers.IO) {
            val result = agrotrackerApi.getAnios()
            if (result.isSuccessful) {
                for (anio in result.body()!!){
                    Log.d(TAG, anio.toString())
                }
            }
        }
        return null
    }

    fun getAnios() {
        //anioDao.getListAnios()
    }

    }

and this is my RepositoryModule:

@Module
@InstallIn(ApplicationComponent::class)
object RepositoryModule {

    @Singleton
    @Provides
    fun providesAnioRepository( agrotrackerApi: AgrotrackerApi) : AnioRepository {
        return AnioRepository(agrotrackerApi)
    }

}

So I'm trying to add Dao class to the Repository Class, like this:

class AnioRepository constructor(
        private val anioDao: AnioDao,
        private val agrotrackerApi: AgrotrackerApi
    ) {
    val TAG = "AnioRepository"
   ...

and then, change RepositoryModule, to match constructor...

...
    fun providesAnioRepository( anioDao: AnioDao, agrotrackerApi: AgrotrackerApi) : AnioRepository 
        =  AnioRepository(anioDao, agrotrackerApi)
...

but when I press Ctrl-F9, i get this error:

public abstract class ATMDatabase extends androidx.room.RoomDatabase { ^C:\pryectos\AndroidStudioProjects\ATMobileXKt\app\build\generated\source\kapt\debug\com\cse\atm\ATMApplication_HiltComponents.java:155: error: [Dagger/MissingBinding] @com.cse.atm.di.ApplicationScope kotlinx.coroutines.CoroutineScope cannot be provided without an @Provides-annotated method. public abstract static class SingletonC implements ATMApplication_GeneratedInjector, ^ @com.cse.atm.di.ApplicationScope kotlinx.coroutines.CoroutineScope is injected at com.cse.atm.database.ATMDatabase.Callback(�, applicationScope) com.cse.atm.database.ATMDatabase.Callback is injected at com.cse.atm.di.AppModule.providesDatabase(�, callback) com.cse.atm.database.ATMDatabase is injected at com.cse.atm.di.AppModule.providesAnioDao(db) com.cse.atm.database.AnioDao is injected at com.cse.atm.di.RepositoryModule.providesAnioRepository(anioDao, �) javax.inject.Provider<com.cse.atm.data.AnioRepository> is injected at

What means this error? What I'm missing ?

@ApplicationScope annotation is in another AppModule.kt, I dont' where is the problem.

Any help wil be appreciated!!

Best Regards


Solution

  • Your ATMDatabase.Callback is requesting a CoroutineScope with custom qualifier @ApplicationScope, but you are not providing such a CoroutineScope in any of your modules.

    To provide a coroutine scope, the tutorial you linked adds this code around the 28-minute mark:

    @Provides
    @Singleton
    fun provideApplicationScope() = CoroutineScope(SupervisorJob())
    

    Since you are using the @ApplicationScope qualifier when requesting a coroutine scope, you will also need to add the qualifier to this @Provides method:

    @Provides
    @Singleton
    @ApplicationScope
    fun provideApplicationScope() = CoroutineScope(SupervisorJob())