Kotlin-inject 多平台项目配置指南
前言
在现代移动应用开发中,多平台开发已成为主流趋势。Kotlin Multiplatform (KMP) 技术允许开发者共享业务逻辑代码,同时为不同平台保留原生UI体验。本文将详细介绍如何在 Kotlin Multiplatform 项目中使用 kotlin-inject 依赖注入框架,实现跨平台的依赖管理解决方案。
项目配置基础
插件配置
首先需要将标准的 Kotlin JVM 插件替换为 Kotlin Multiplatform 插件:
plugins {
id("org.jetbrains.kotlin.multiplatform")
id("com.google.devtools.ksp")
}
目标平台设置
配置项目支持的目标平台,包括 Android 和 iOS 各架构:
kotlin {
androidTarget()
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "shared"
}
}
}
运行时依赖
在 commonMain 源集中添加 kotlin-inject 的运行时依赖:
sourceSets {
commonMain {
dependencies {
implementation("me.tatarka.inject:kotlin-inject-runtime-kmp:0.8.0")
}
}
}
注意:kotlin-inject-runtime-kmp 与标准运行时库的主要区别在于增加了 KmpComponentCreate 注解支持。
KSP 编译器配置
Kotlin Symbol Processing (KSP) 是 kotlin-inject 实现代码生成的关键。在多平台项目中,代码生成有两种策略:
- 公共源集生成:所有生成的代码放在 commonMain 中
- 目标平台生成:为每个目标平台单独生成代码
编译器依赖配置
dependencies {
// 公共源集生成方式
kspCommonMainMetadata(libs.kotlinInject.compiler)
// 目标平台生成方式
add("kspAndroid", libs.kotlinInject.compiler)
add("kspIosX64", libs.kotlinInject.compiler)
add("kspIosArm64", libs.kotlinInject.compiler)
add("kspIosSimulatorArm64", libs.kotlinInject.compiler)
}
注意:同时配置两种生成方式可能导致组件重复声明问题。
多平台组件创建
在多平台环境中创建组件面临特殊挑战:
基础方案
// commonMain
@Component
abstract class MyKmpComponent
expect fun createKmp(): MyKmpComponent
// 各平台实现
actual fun createKmp(): MyKmpComponent = MyKmpComponent::class.create()
简化方案 - KmpComponentCreate
kotlin-inject 提供了 @KmpComponentCreate 注解简化这一过程:
@Component
abstract class MyKmpComponent
@KmpComponentCreate
expect fun createKmp(): MyKmpComponent
注解会自动生成各平台的 actual 实现:
actual fun createKmp(): MyKmpComponent = MyKmpComponent::class.create()
扩展函数形式
更优雅的命名空间管理方式:
@KmpComponentCreate
expect fun MyKmpComponent.Companion.createKmp(): MyKmpComponent
对应生成的代码:
actual fun MyKmpComponent.Companion.createKmp(): MyKmpComponent = MyKmpComponent::class.create()
共享源集支持
KmpComponentCreate 不仅适用于 commonMain,也可用于其他共享源集,如 iOS 专用共享代码:
// ios 共享源集
@KmpComponentCreate
expect fun MyKmpComponent.Companion.createKmp(): MyKmpComponent
val myKmpComponent: MyKmpComponent = MyKmpComponent.createKmp()
公共源集 KSP 配置
完整配置示例:
kotlin {
commonMain {
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
}
}
tasks.withType<KspAATask>().configureEach {
if (name != "kspCommonMainKotlinMetadata") {
dependsOn("kspCommonMainKotlinMetadata")
}
}
最佳实践建议
- 组件设计原则:将平台无关的依赖定义在 commonMain 中,平台特定实现放在各自目标源集
- 性能考量:对于大型项目,目标平台生成方式可能带来更好的编译性能
- 版本兼容:注意 Kotlin 2.0 后对源集可见性的改变,避免跨源集非法访问
- 测试策略:为公共组件编写跨平台测试,确保各平台行为一致
通过合理运用 kotlin-inject 的多平台支持特性,开发者可以构建出既保持代码共享优势,又不失平台特性的高质量应用架构。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



