androidkotlinandroid-jetpack-composedagger-hilt

Is there something wrong with my dao. How do I fix this error?


Error I am facing ->

C:\Users\***\Downloads\ToDoList\app\build\generated\hilt\component_sources\debug\com\example\todolist\TASKapp_HiltComponents.java:128: error: [Dagger/MissingBinding] com.example.todolist.Domain.TaskRepo cannot be provided without an @Provides-annotated method.
  public abstract static class SingletonC implements TASKapp_GeneratedInjector,
                         ^
  
      com.example.todolist.Domain.TaskRepo is injected at
          [com.example.todolist.TASKapp_HiltComponents.SingletonC] com.example.todolist.DI.Module.provideRepoImpl(repo)
      com.example.todolist.Domain.UseCases.UseCases is injected at
          [com.example.todolist.TASKapp_HiltComponents.ViewModelC] com.example.todolist.Presentation.ViewModels.Edit.editViewModel(useCases, �)
      com.example.todolist.Presentation.ViewModels.Edit.editViewModel is injected at
          [com.example.todolist.TASKapp_HiltComponents.ViewModelC] com.example.todolist.Presentation.ViewModels.Edit.editViewModel_HiltModules.BindsModule.binds(vm)
      @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.Class<?>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
          [com.example.todolist.TASKapp_HiltComponents.ViewModelC] dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.example.todolist.TASKapp_HiltComponents.SingletonC ? com.example.todolist.TASKapp_HiltComponents.ActivityRetainedC ? com.example.todolist.TASKapp_HiltComponents.ViewModelC]

So these are my gradle files and Dao->

Dao file ->



package com.example.todolist.DI

import android.app.Application
import androidx.core.app.AppLocalesStorageHelper
import androidx.room.Databaseimport androidx.room.Room
import androidx.room.RoomDatabase
import com.example.todolist.Data.Task
import com.example.todolist.Data.TaskDatabase
import com.example.todolist.Data.TaskRepoImpl
import com.example.todolist.Domain.TaskRepo
import com.example.todolist.Domain.UseCases.UseCases
import com.example.todolist.Domain.UseCases.deleteNote
import com.example.todolist.Domain.UseCases.getNotes
import com.example.todolist.Domain.UseCases.getTaskById
import com.example.todolist.Domain.UseCases.insertTask
import dagger.Moduleimport dagger.Providesimport dagger.hilt.InstallInimport dagger.hilt.components.SingletonComponent
import javax.inject.Singleton@InstallIn(SingletonComponent::class)
@Moduleobject Module {
    @Provides    @Singleton    fun provideDatabase(app:Application):TaskDatabase{
        return Room.databaseBuilder(app,TaskDatabase::class.java,"database").build()
    }
    @Provides    @Singleton    fun provideRepo(
        database: TaskDatabase
    ):TaskRepoImpl{
        return TaskRepoImpl(database.taskDAO)
    }

    @Provides    @Singleton    fun provideRepoImpl(
        repo: TaskRepo
    ):UseCases{
        return UseCases(
            deleteNote = deleteNote(repo),
            getTask = getNotes(repo),
            getTaskById = getTaskById(repo),
            insertTask = insertTask(repo)
        )
    }
}



Gradle File->



plugins {    alias(libs.plugins.android.application)
    alias(libs.plugins.jetbrains.kotlin.android)
    id("kotlin-kapt")
    id("com.google.dagger.hilt.android")
    id("androidx.room")

}android {    namespace = "com.example.todolist"    compileSdk = 34    defaultConfig {        applicationId = "com.example.todolist"        minSdk = 24        targetSdk = 34        versionCode = 1        versionName = "1.0"        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"        vectorDrawables {            useSupportLibrary = true        }    }    buildTypes {        release {            isMinifyEnabled = false            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"            )
        }    }    compileOptions {        sourceCompatibility = JavaVersion.VERSION_1_8        targetCompatibility = JavaVersion.VERSION_1_8    }    kotlinOptions {        jvmTarget = "1.8"    }    buildFeatures {        compose = true    }    composeOptions {        kotlinCompilerExtensionVersion = "1.5.1"    }    packaging {        resources {            excludes += "/META-INF/{AL2.0,LGPL2.1}"        }    }    room {        schemaDirectory("$projectDir/schemas")
    }}dependencies {    val room_version = "2.6.1"    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor("androidx.room:room-compiler:$room_version")

    // To use Kotlin annotation processing tool (kapt)    kapt("androidx.room:room-compiler:$room_version")
    implementation("androidx.room:room-ktx:$room_version")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
    implementation("com.google.dagger:hilt-android:2.51.1")
    kapt("com.google.dagger:hilt-android-compiler:2.51.1")
}kapt {    correctErrorTypes = true}


Another Gradle File ->



modules.plugins {    alias(libs.plugins.android.application) apply false    alias(libs.plugins.jetbrains.kotlin.android) apply false    id("com.google.dagger.hilt.android") version "2.51.1" apply false    id("androidx.room") version "2.6.1" apply false}


Repo usecase file ->



package com.example.todolist.Data

import com.example.todolist.Domain.TaskRepo
import kotlinx.coroutines.flow.Flow

class TaskRepoImpl(
    private val taskDAO: TaskDAO
): TaskRepo{
    override fun getTasks(): Flow<List<Task>> {
        return taskDAO.getAllTasks()
    }
    override suspend fun deleteTask(task: Task) {
        taskDAO.deleteNote(task)
    }
    override suspend fun getTaskById(id: Int): Task{
        return taskDAO.getTaskbyId(id)
    }
    override suspend fun insert(task: Task) {
        taskDAO.insertNote(task)
    }
}



Repo file ->



package com.example.todolist.Domain

import com.example.todolist.Data.Task
import dagger.Providesimport kotlinx.coroutines.flow.Flow

interface TaskRepo {
    fun getTasks(): Flow<List<Task>>;
    suspend fun deleteTask(task: Task);
    suspend fun getTaskById(id:Int) : Task?;
    suspend fun insert(task: Task);
}


What should i do to fix this??

I tried the following blog but it didn't help me with the problem ->

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


Solution

  • The problem isn't your DAO, it's your injection framework can't find a constructor for a TaskRepo. You have a mistake in your provider:

    @Provides    @Singleton    fun provideRepo(
        database: TaskDatabase
    ):TaskRepoImpl{
        return TaskRepoImpl(database.taskDAO)
    }
    

    This should be returning a TaskRepo, not a TaskRepoImpl. Because it doesn't return the interface type, Dagger doesn't realize that it's the TaskRepo needed by other classes being injected.