带注解的 Kotlin 多平台依赖注入
Kotlin Multiplatform Dependency Injection with Annotations
我正尝试在我的 Kotlin Multiplatform 项目中使用这个库进行依赖注入 - https://github.com/corbella83/PopKorn
该库基于 kapt
,Android 部分完美运行!但是,我很难理解为什么 iOS 似乎不起作用(我已经在他们的末端提交了一个问题,但想在这里问一下,以防我发出一些明显的问题)。
我有一个来自 KMM Android Studio 插件的开箱即用的 vanilla KMM 项目,具有以下依赖相关设置:
// In shared/build.gradle.kts
kotlin {
...
sourceSets {
val commonMain by getting {
dependencies {
implementation("cc.popkorn:popkorn:2.1.1")
}
}
}
}
dependencies {
"kapt" ("cc.popkorn:popkorn-compiler:2.1.1") <- SHOULD THIS BE HERE?
}
// In androidApp/build.gradle.kts
dependencies {
implementation("cc.popkorn:popkorn:2.1.1")
}
// In commonMain source set
@Injectable
class Greeting {
fun greeting(): String {
return "Hello, ${Platform().platform}!"
}
}
// In MainActivity.kt
val greeting by popkorn<Greeting>() <- WORKS!
// In iosMain/Bridge.kt
fun init(creator: (ObjCClass) -> Mapping) = cc.popkorn.setup(creator)
fun getInjector() = InjectorObjC(popKorn())
// In iosApp
@main
struct iOSApp: App {
init() {
BridgeKt.doInit { (clazz) -> PopkornMapping in
return clazz.alloc() as! PopkornMapping
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// In ContentView.swift
let greet = (BridgeKt.getInjector().inject(clazz: Greeting.self) as! Greeting).greeting()
我的错误是 Could not find Provider for this class: com.example.myapplication.Greeting. Did you forget to add @Injectable?
这显然不是真的,因为我有注释。
我担心的是,当 android 编译时,我可以看到一些与使用 PopKorn 生成注释相关的日志,但是当我使用以下 [=40] 构建 iOS 应用程序时,我没有看到这些=]脚本(新建项目时默认):
./gradlew :shared:embedAndSignAppleFrameworkForXcode
kapt
是否需要任何其他设置才能在 iOS 上工作?
我最终使用了一个不同的库来为 Kotlin Multiplatform (Kodein) 进行依赖注入,但对于它的价值,我认为这对任何遇到类似问题的人来说都是有帮助的,知道我是如何解决它的。关键是使用以下方法将生成的代码公开给 Swift:
val iosMain by getting {
...
kotlin.srcDir("${buildDir.absolutePath}/generated/source/kaptKotlin/")
}
在此之后,来自 Swift 的注入工作正常。然而,我最终在尝试从多个模块注入东西时遇到了更多问题,我觉得 Kodein 对我目前正在尝试做的事情有更好的支持。
我正尝试在我的 Kotlin Multiplatform 项目中使用这个库进行依赖注入 - https://github.com/corbella83/PopKorn
该库基于 kapt
,Android 部分完美运行!但是,我很难理解为什么 iOS 似乎不起作用(我已经在他们的末端提交了一个问题,但想在这里问一下,以防我发出一些明显的问题)。
我有一个来自 KMM Android Studio 插件的开箱即用的 vanilla KMM 项目,具有以下依赖相关设置:
// In shared/build.gradle.kts
kotlin {
...
sourceSets {
val commonMain by getting {
dependencies {
implementation("cc.popkorn:popkorn:2.1.1")
}
}
}
}
dependencies {
"kapt" ("cc.popkorn:popkorn-compiler:2.1.1") <- SHOULD THIS BE HERE?
}
// In androidApp/build.gradle.kts
dependencies {
implementation("cc.popkorn:popkorn:2.1.1")
}
// In commonMain source set
@Injectable
class Greeting {
fun greeting(): String {
return "Hello, ${Platform().platform}!"
}
}
// In MainActivity.kt
val greeting by popkorn<Greeting>() <- WORKS!
// In iosMain/Bridge.kt
fun init(creator: (ObjCClass) -> Mapping) = cc.popkorn.setup(creator)
fun getInjector() = InjectorObjC(popKorn())
// In iosApp
@main
struct iOSApp: App {
init() {
BridgeKt.doInit { (clazz) -> PopkornMapping in
return clazz.alloc() as! PopkornMapping
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// In ContentView.swift
let greet = (BridgeKt.getInjector().inject(clazz: Greeting.self) as! Greeting).greeting()
我的错误是 Could not find Provider for this class: com.example.myapplication.Greeting. Did you forget to add @Injectable?
这显然不是真的,因为我有注释。
我担心的是,当 android 编译时,我可以看到一些与使用 PopKorn 生成注释相关的日志,但是当我使用以下 [=40] 构建 iOS 应用程序时,我没有看到这些=]脚本(新建项目时默认):
./gradlew :shared:embedAndSignAppleFrameworkForXcode
kapt
是否需要任何其他设置才能在 iOS 上工作?
我最终使用了一个不同的库来为 Kotlin Multiplatform (Kodein) 进行依赖注入,但对于它的价值,我认为这对任何遇到类似问题的人来说都是有帮助的,知道我是如何解决它的。关键是使用以下方法将生成的代码公开给 Swift:
val iosMain by getting {
...
kotlin.srcDir("${buildDir.absolutePath}/generated/source/kaptKotlin/")
}
在此之后,来自 Swift 的注入工作正常。然而,我最终在尝试从多个模块注入东西时遇到了更多问题,我觉得 Kodein 对我目前正在尝试做的事情有更好的支持。