简体   繁体   中英

How to implement Koin dependency injection in Room MVVM Architecture

I'm following this documentation to implement koin dependency injection but it couldn't help me. I'm stuck in Modules.kt file I don't know how to pass DAO interface of Database to Repository constructor in module of koin.

UserEntity.kt

@Entity(tableName = "user_table")
data class UserEntity(...)

UserDao.kt

@Dao
interface UserDao { ... }

UserRepository.kt

class UserRepository(private val userDao: UserDao) {...}

UserViewModel.kt

class UserViewModel(private val repository: UserRepository) : ViewModel() {...}

UserDatabase.kt

@Database(
    entities = [UserEntity::class],
    version = 1,
    exportSchema = false
)
abstract class UserDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao

    companion object {

        @Volatile
        private var INSTANCE: UserDatabase? = null
        fun getDatabase(context: Context, scope: CoroutineScope): UserDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    UserDatabase::class.java,
                    "user_data_database"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

Modules.kt Here is Koin Modules

val appModule = module{

    single { UserRepository(get()) }

    viewModel { UserViewModel(get()) }

}

First of all in your class file which you extend from Room Database class. You will need to create an abstract function to provide Instance of your Dao Interface like this ,

@Database(entities = [Run::class],version = 1 , exportSchema = false)
abstract class RunningDatabase : RoomDatabase() {

abstract fun getRunDao(): RunDao
}

Then in your module provide the Instance for Room Database like this,

single {
   Room.databaseBuilder(
     androidApplication,
     RunningDatabase::class.java,
     RUNNING_DATABASE_NAME
 ).build()
}

Now you can call the abstract function of Room Database class to get the Instance of Dao Interface. Like this,

single<RunningDao> {
  val database = get<RunningDatabase>()
  database.getRunDao()
}

Now you can pass this Interface in any constructor.

In My Case, I just added Koin Module in the Application class and got the database to pass the DAO interface to the Repository constructor in the module of koin. Here is full example.

class MainApplication:Application() {

    private val applicationScope = CoroutineScope(SupervisorJob())
    private val database by lazy { UserDatabase.getDatabase(this,applicationScope) }


    override fun onCreate() {
        super.onCreate()
        startKoin{
            androidContext(this@MainApplication)
            modules(listOf(appModule))
        }
    }

    private val appModule = module{
        single { database.userDao() }

        single { UserRepository(get()) }

        single { UserViewModel(get()) }
   
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM