Using dagger-hilt in repository class

Viewed 3629

Please consider the following class:

class MainRepository constructor(
    private val blogDao: BlogDao,
    private val blogRetrofit: BlogRetrofit,
    private val cacheMapper: CacheMapper,
    private val networkMapper: NetworkMapper
){
    .....
}

If i want to convert the MainRepository class to use dagger-hilt for passing in arguments, is it enough to add @Inject before construcor, like so??

class MainRepository @Inject constructor(
    private val blogDao: BlogDao,
    private val blogRetrofit: BlogRetrofit,
    private val cacheMapper: CacheMapper,
    private val networkMapper: NetworkMapper
){

Or needs more??

2 Answers

Yes, that is enough. But if you want to make your life easier for testing, consider adding a Interface to the MainRepository like this:

interface MainRepository {
   // your functions
}

And then the Implementation

@Singleton
class MainRepositoryImpl @Inject constructor(
     // your dependencies
) : MainRepository

And finally, in your Di.Modules

@Module
@InstallIn(ApplicationComponent::class) // or whatever graph fits your need the best
interface RepositoryModules {
    @Binds
    fun provideMainRepositoryImpl(repository: MainRepositoryImpl): MainRepository
}

You could then use your repository like the following

class ExampleRepositoryUsageClass @Inject constructor(
     private val mainrepository: MainRepository // MainRepositoryImpl is injected here
)

In order to inject dependencies into a repository implementation, the dependencies can be inject in the constructor with the annotation @Inject. For this @Inject to work, 2 other things are needed. Binding the dependency for the repository in a repository module with the @Binds annotation, and providing the dependencies that are passed to the repository's constructor with the annotation @Provides.

@Inject dependencies into the repository's constructor:

class MainRepository @Inject constructor(
    private val blogDao: BlogDao,
    private val blogRetrofit: BlogRetrofit,
    private val cacheMapper: CacheMapper,
    private val networkMapper: NetworkMapper
) { ... }

@Binds the dependency for the repository in a repository module, MyRepositoryModule.kt, you want to install the module in ViewModelComponent as repositories are usually should be in view models.

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent

@Module
@InstallIn(ViewModelComponent::class)
interface MyRepositoryModules {
    @Binds
    fun provideMainRepository(repository: MainRepository): MainRepository
}

@Provides the dependencies that are passed to the repository's constructor in a module, MyModules.kt

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@InstallIn(ViewModelComponent::class)
@Module
object MyModule {
    @Provides
    fun provideBlogDao(): BlogDao {
        // code for creating BlogDao
        return BlogDao()
    }

    @Provides
    fun provideBlogRetrofit(): BlogRetrofit {
        // code for creating BlogRetrofit
        return BlogRetrofit()
    }
    @Provides
    fun provideCacheMapper(): CacheMapper {
        // code for creating CacheMapper
        return CacheMapper()
    }
    @Provides
    fun provideNetworkMapper(): NetworkMapper {
        // code for creating NetworkMapper
        return NetworkMapper()
    }
}

For any dependencies that are used to inject into a repository or anywhere, they have to be exist, that means they need to be defined in a module with the @Provides annotation before it is being injected.

Related