Home > Mobile >  Dagger Hilt - Missing Binding for CoroutineDispatcher
Dagger Hilt - Missing Binding for CoroutineDispatcher

Time:10-12

I'll start off with the caveat that I have read this answer, however it doesn't explain my situation just to avoid the duplicate question posts.

I am creating a basic app to get to grips with Hilt.

I am developing with MVVM, viewmodel, usecase, repository. I have structured my hilt modules as follows CoroutineModule

@Module
@InstallIn(ViewModelComponent::class)
object CoroutineModule {

    @DefaultDispatcher
    @Provides
    fun provideDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default

    @IoDispatcher
    @Provides
    fun provideIODispatcher(): CoroutineDispatcher = Dispatchers.IO

    @MainDispatcher
    @Provides
    fun provideMainDispatcher(): CoroutineDispatcher = Dispatchers.Main

    @MainImmediateDispatcher
    @Provides
    fun providesMainImmediateDispatcher(): CoroutineDispatcher = Dispatchers.Main.immediate
}

CoroutineQualifiers.kt

import javax.inject.Qualifier

@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class DefaultDispatcher

@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class IoDispatcher

@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class MainDispatcher

@Retention(AnnotationRetention.BINARY)
@Qualifier
annotation class MainImmediateDispatcher

RepositoryModule

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

    @Singleton
    @Provides
    fun provideWeatherRepository(weatherService: WeatherService, defaultDispatcher: CoroutineDispatcher) =
        WeatherRepository(weatherService, defaultDispatcher)
}

UseCaseModule

@Module
@InstallIn(SingletonComponent::class)
object UseCaseModule {

    @Singleton
    @Provides
    fun provideGetWeatherUseCase(repository: WeatherRepository, mapper: WeatherForecastMapper) =
        GetWeatherForecastUseCase(repository, mapper)
}

Weather Respository Constructor

class WeatherRepository @Inject constructor(
    private val weatherService: WeatherService,
    @IoDispatcher private val dispatcher: CoroutineDispatcher
)

When I build the app I get the error below. I am sure there is a very simple error I'm not seeing. If someone could point me towards it I'd appreciate it!

[Dagger/MissingBinding] kotlinx.coroutines.CoroutineDispatcher cannot be provided without an @Provides-annotated method.
  public abstract static class SingletonC implements WeatherApplication_GeneratedInjector,
                         ^
      kotlinx.coroutines.CoroutineDispatcher is injected at
          com.gary.weather.di.RepositoryModule.provideWeatherRepository(…, defaultDispatcher)
      com.gary.weather.data.repositories.WeatherRepository is injected at
          com.gary.weather.di.UseCaseModule.provideGetWeatherUseCase(repository, …)
      com.gary.weather.features.weathersummary.domain.usecases.GetWeatherForecastUseCase is injected at
          com.gary.weather.features.weathersummary.view.WeatherSummaryViewModel(getWeatherForecastUseCase)
      com.gary.weather.features.weathersummary.view.WeatherSummaryViewModel is injected at
          com.gary.weather.features.weathersummary.view.WeatherSummaryViewModel_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() [com.gary.weather.WeatherApplication_HiltComponents.SingletonC → com.gary.weather.WeatherApplication_HiltComponents.ActivityRetainedC → com.gary.weather.WeatherApplication_HiltComponents.ViewModelC]

CodePudding user response:

You need to specify what CoroutineDispatcher you want to inject there. It's trying to find something that provides unqualified CoroutineDispatcher.

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

    @Singleton
    @Provides
    fun provideWeatherRepository(
        weatherService: WeatherService, 
        @IoDispatcher ioDispatcher: CoroutineDispatcher
    ) = WeatherRepository(weatherService, ioDispatcher)
}

Also as mentioned, if you want module to provide it, remove the @Inject from the constructor of the WeatherRepository

  • Related