Koin 是务实的 Kotlin 依赖注入方案,适用于 Android 与 KMP 项目。与 Hilt 相比,Koin 可运行在 commonMain(Hilt 不行),并通过 verify() 校验依赖图而非代码生成;Hilt 仅限 Android,带代码生成与 Jetpack 深度集成(@HiltViewModel / hiltViewModel())。
主要能力与用法:模块声明支持 Classic DSL(single、factory、scoped、viewModel { },配合 get() 解析与运行时参数)与 KSP 注解。注解方式用 @Module @ComponentScan 扫描带注解类并生成模块,需在 startKoin 中传入 UserModule().module(即生成的 .module 扩展,最易遗漏)。同一模块内不要混用 Classic DSL 与注解,模块之间切换可以。注解示例包括 @Single、@Factory、@KoinViewModel(支持 @InjectedParam)。依赖通过 koin-bom 管理,含 koin-core、koin-android、koin-androidx-compose、koin-compose-viewmodel、koin-compose-viewmodel-navigation(Nav 3)、koin-test,以及可选的 koin-annotations / koin-ksp-compiler。
KMP 源集布局:多数绑定放在 commonMain,平台相关绑定(HTTP 引擎、Context、Keychain)通过 expect val platformModule: Module 在各平台 actual 提供,与 kmp-ktor 的引擎模式一致。iOS 启动需在 iOSApp.init() 调用 InitKoinKt.doInitKoin(config: nil)(Swift 保留 init,故加 do 前缀)。
Compose:koinViewModel / koinInject 依赖 koin-androidx-compose 或 koin-compose-viewmodel,缺少该产物会编译通过但在调用点失败。为便于测试可将 composable 参数默认值设为 koinInject()。
作用域:跨配置变更存活用 activityRetainedScope,以 activityRetainedScope { }(或 @ActivityRetainedScope)声明并通过 AndroidScopeComponent 访问;自定义生命周期用 scope<T> 自行管理 createScope、get 与 close。Nav 3 用 koinEntryProvider() 按目的地解析 ViewModel,目的地注册在模块内。
测试:checkModules() / verify() 遍历声明构造函数并确认依赖已声明,将缺失绑定变为测试失败;对运行时解析参数(如 SavedStateHandle)需传 extraTypes。可用假实现覆盖真实绑定,KoinTestRule(JUnit 4)/ KoinTestExtension(JUnit 5)为每个测试安装上下文。限制:资料未提供具体版本要求、性能数据或非 Android/KMP 平台支持信息。