Search code examples
androiddependency-injectioninterfacerepositorydagger-hilt

Android Hilt cannot be provided without an @Provides-annotated method. in repository Interface Class


I'm getting this error error: [Dagger / MissingBinding] com.eduramza.domain.repositories.RemoteRepository cannot be provided without an @ Provides-annotated method. when implementing my repository interface with android hilt.

That's because my useCase implements my repository interface. What may be wrong with my implementation, below is the code:

app.Viewmodel:

@HiltViewModel
class RemoteListViewModel @Inject constructor(
    private val useCase: GetTickersUseCase
    ): ViewModel() {
}

domain.usecase:

class GetTickersUseCase @Inject constructor(
    private val remoteRepository: RemoteRepository)
    : SingleUseCase<MainCoins> {

    override suspend fun executeCall(): Flow<Result<MainCoins>> = remoteRepository.readAllTickers()

}

domain.repository:

interface RemoteRepository {
    suspend fun readAllTickers(): Flow<Result<MainCoins>>
}

core.repositoryImpl:

class RemoteRepositoryImpl @Inject constructor(
    private val apiService: BraziliexService,
    private val tickersMapper: TickersMapper
) : RemoteRepository{

    override suspend fun readAllTickers(): Flow<Result<MainCoins>> {
        TODO("Not yet implemented")
    }
}

core.module:

@Module
@InstallIn(ActivityComponent::class)
abstract class RemoteModule {

@Binds
abstract fun bindRemoteRepository(
    remoteRepositoryImpl: RemoteRepositoryImpl
    ): RemoteRepository
}

My multimodule app in this structure enter image description here where core implement domain, and app implement both.

why is the bind method not being initialized?

enter image description here


Solution

  • You using the ActivityComponent but the RemoteRepository is the indirect dependency of ViewModel so it should be tied with the ViewModel Lifecycle

    so instead of ActivityComponent

    @Module
    @InstallIn(ActivityComponent::class)
    abstract class RemoteModule {
    
    @Binds
    abstract fun bindRemoteRepository(
        remoteRepositoryImpl: RemoteRepositoryImpl
        ): RemoteRepository
    }
    

    Use this ViewModelComponent

    @Module
        @InstallIn(ViewModelComponent::class)
        abstract class RemoteModule {
        
        @Binds
        abstract fun bindRemoteRepository(
            remoteRepositoryImpl: RemoteRepositoryImpl
            ): RemoteRepository
        }