如何在Compose Multiplatform中用Kodein提供SqlDelight数据库
解决KMM中Kodein注入DriverFactory的跨平台依赖问题
核心思路
利用KMM的expect/actual机制,将DriverFactory的绑定逻辑下沉到各平台专属的DI配置中,共享模块只依赖抽象的DriverFactory类型,不关心具体实现。
方案一:拆分DI模块为「共享基础模块」+「平台专属模块」
1. 调整共享层的dataModule
移除DriverFactory的绑定,只保留依赖它的服务:
// 共享模块/dataModule.kt val dataModule = DI.Module(name = "dataModule") { // 依赖注入DriverFactory(由平台模块提供) bindSingleton { LocalDatabase(instance()) } bindProvider<SavedTeamRepository> { SavedTeamRepositoryImpl(instance()) } }
2. Android平台配置
在Android端的DI模块中,先绑定Context,再提供Android版的DriverFactory:
// Android平台/AndroidPlatformModule.kt val androidPlatformModule = DI.Module(name = "androidPlatformModule") { // 绑定Android Context(可通过Kodein-android扩展的androidContext()获取) bindSingleton { androidContext() } // 绑定Android专属的DriverFactory实现 bindSingleton<DriverFactory> { DriverFactory(instance()) } }
在Android应用中组合模块:
// Android应用/AppDI.kt val appDI = DI { import(androidPlatformModule) import(dataModule) }
3. iOS平台配置
iOS版DriverFactory无需额外参数,直接绑定即可:
// iOS平台/IosPlatformModule.kt val iosPlatformModule = DI.Module(name = "iosPlatformModule") { bindSingleton<DriverFactory> { DriverFactory() } }
在iOS端初始化DI时导入模块:
// iOS端/AppDI.swift let di = DI { import(iosPlatformModule) import(dataModule) }
方案二:用expect/actual封装平台绑定逻辑(更简洁)
1. 共享层定义绑定逻辑的expect函数
// 共享模块/DriverFactoryBinding.kt expect fun DI.Builder.bindDriverFactory() // 共享模块/dataModule.kt val dataModule = DI.Module(name = "dataModule") { // 调用平台实现的绑定逻辑 bindDriverFactory() bindSingleton { LocalDatabase(instance()) } bindProvider<SavedTeamRepository> { SavedTeamRepositoryImpl(instance()) } }
2. Android平台实现绑定函数
// Android平台/DriverFactoryBinding.kt actual fun DI.Builder.bindDriverFactory() { bindSingleton { androidContext() } bindSingleton<DriverFactory> { DriverFactory(instance()) } }
3. iOS平台实现绑定函数
// iOS平台/DriverFactoryBinding.kt actual fun DI.Builder.bindDriverFactory() { bindSingleton<DriverFactory> { DriverFactory() } }
为什么原来的方式行不通?
expect class DriverFactory本身是抽象的,没有具体构造逻辑,无法直接在共享模块中提供实例;- Android版
DriverFactory依赖Context,这个对象是Android平台独有的,只能在Android端的DI配置中注入。
内容的提问来源于stack exchange,提问作者alfietap
相关产品推荐
相关产品推荐

