You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:57:28