简体   繁体   English

如何在 Room MVVM 架构中实现 Koin 依赖注入

[英]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.我正在按照这个文档来实现 koin 依赖注入,但它对我没有帮助。 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.我被困在Modules.kt文件中,我不知道如何将数据库的 DAO 接口传递给 koin module中的Repository构造函数。

UserEntity.kt用户实体.kt

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

UserDao.kt用户道.kt

@Dao
interface UserDao { ... }

UserRepository.kt用户存储库.kt

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

UserViewModel.kt用户视图模型.kt

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

UserDatabase.kt用户数据库.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 Modules.kt这是 Koin 模块

val appModule = module{

    single { UserRepository(get()) }

    viewModel { UserViewModel(get()) }

}

First of all in your class file which you extend from Room Database class.首先,在从 Room Database 类扩展的类文件中。 You will need to create an abstract function to provide Instance of your Dao Interface like this ,您将需要创建一个抽象函数来提供这样的 Dao 接口的实例,

@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.现在可以调用 Room Database 类的抽象函数来获取 Dao 接口的实例。 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.在我的案例中,我只是在 Application class 中添加了 Koin 模块,并让数据库将 DAO 接口传递给 koin 模块中的 Repository 构造函数。 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()) }
   
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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