Hi everyone! I'm currently migrating to Koin 4.2.0...
# koin
t
Hi everyone! I'm currently migrating to Koin 4.2.0 (using the new Compiler Plugin) on a Compose Multiplatform app, and I'm stuck on a compilation error on the iOS side. I have a dependency (
ScreenOrientationManager
) that requires native iOS elements (callbacks, native views). Because of this, I declare it dynamically at runtime using the classic DSL in my
iosMain
. However, the Koin compiler fails the build of my
commonMain
because it can't find this definition during its compile-time checks.
Copy code
/***/***/shared/src/commonMain/kotlin/*/*/*/shared/ui/App.kt:52:36 [Koin] Missing definition: *.*.*.*.ScreenOrientationManager
My iOS setup (
iosMain
):
Copy code
val platformModule = module {    
    single<NativeViewProvider> { nativeViewProvider }
    single<ScreenOrientationListener> { ScreenOrientationListener(onOrientationChanged) }
    single<ScreenOrientationManager> { ScreenOrientationManagerIos(screenOrientationListener = get()) }
}

startKoin(platformModule = platformModule, isDebug = Platform.isDebugBinary)
My shared setup (
commonMain
):
Copy code
@KoinApplication(modules = [SharedKoinModule::class])
internal class KoinApp

internal fun startKoin(
    platformModule: Module,
    isDebug: Boolean,
) {
    startKoin<KoinApp> {
        modules(platformModule)
    }
    // ...
}

@Module
@ComponentScan("*.*.*.shared")
internal class SharedKoinModule
The injection point that crashes the compiler (
App.kt
in
commonMain
):
Copy code
val screenOrientationManager: ScreenOrientationManager = koinInject()
It seems the Koin compiler (compile-time safety) completely ignores my
platformModule
injected at runtime, which causes the
@KoinApplication
check to fail. What is the best practice in 4.2.x to inject dependencies that are tightly coupled to the native UI (runtime) without triggering the
[Koin] Missing definition
error from the Compiler Plugin? Thanks in advance for your help!
For context, the rest of my annotated dependencies are successfully organized across files/classes like
CoreKoinModule
in
commonMain
,
CoreKoinModule.ios
in
iosMain
, etc.
t
disable the compile safety, maybe this could fix you error.
t
How ?
I managed to work around the issue, but it feels quite hacky. I added a dummy
@Single
definition on the iOS side just so the KSP compiler plugin can "see" that a `ScreenOrientationManager`is provided during compile-time:
Copy code
@Single
internal fun ScreenOrientationManager(): ScreenOrientationManager = ScreenOrientationManagerIos(
    ScreenOrientationListener {}
)
And I kept my runtime DSL module exactly as it was:
Copy code
val platformModule = module {
    single<NativeViewProvider> { nativeViewProvider }
    single<ScreenOrientationListener> { ScreenOrientationListener(onOrientationChanged) }
    single<ScreenOrientationManager> { ScreenOrientationManagerIos(screenOrientationListener = get()) }
}

startKoin(platformModule = platformModule, isDebug = Platform.isDebugBinary)
At runtime, the DSL definition overrides the dummy annotated one, so the correct instance is used. Does anyone have a cleaner solution to properly include a runtime
platformModule
in the compiler plugin checks without resorting to dummy definitions? I'd love to hear your thoughts!
t
Inside all your module that have the compiler, you have a dsl access for configuration
Copy code
koinCompiler {
//    userLogs = true
//    debugLogs = true
    compileSafety = false
//    unsafeDslChecks = false
}
Can be seen in the readme of the project: https://github.com/InsertKoinIO/koin-compiler-plugin
t
Hello, I resolved my problem with the @Provided annotation:
Copy code
@Single
internal fun screenOrientationManager(
    @Provided screenOrientationListener: ScreenOrientationListener
): ScreenOrientationManager = ScreenOrientationManagerIos(
    screenOrientationListener = screenOrientationListener
)
Thanks to @arnaud.giuliani for the solution in your Droidcon presentation.
👍 1
a
cool 🙂