I'm not able to run a simple example with Koin (4....
# koin
r
I'm not able to run a simple example with Koin (4.1) + KMP (Web & desktop target) + Koin Annotations (4.0,1RC) , having this error
Copy code
[ksp] --> Missing Definition for property 'settings : com.russhwolf.settings.Settings' in 'com.binshelve.data.local.UserRepository'. Fix your configuration: add definition annotation on the class.
🧵 1
1
k
share you local repository setup i.e
Copy code
class LocalRepository(....)
r
I've a shared module with this class in commonMain
Copy code
package com.binshelve.shared.data

import com.russhwolf.settings.Settings
import org.koin.core.annotation.Factory
import org.koin.core.annotation.Module

@Module
expect class SettingsModule() {
    @Factory
    fun providesSettings(): Settings
}

expect fun settings(): Settings
And the actual implementations (Wasm as example)
Copy code
package com.binshelve.shared.data

import com.russhwolf.settings.Settings
import com.russhwolf.settings.StorageSettings
import org.koin.core.annotation.Factory
import org.koin.core.annotation.Module
import org.koin.core.annotation.Single

@Module
actual class SettingsModule actual constructor() {
    @Factory
    actual fun providesSettings() = settings()
}

actual fun settings(): Settings = StorageSettings()
Also in my app gradle module, I have this
Copy code
package com.binshelve.ui.components

import androidx.compose.runtime.Composable
import com.binshelve.data.di.DataModule
import com.binshelve.shared.SharedModule
import com.binshelve.ui.di.UIModule
import com.binshelve.ui.screen.application.applicationsUiModule
import com.binshelve.usecases.di.UseCasesModule
import org.koin.compose.KoinApplication
import org.koin.ksp.generated.module

@Composable
fun Koin(content: @Composable () -> Unit) {
    KoinApplication(
        application = {
            modules(
                UIModule().module,
                DataModule().module,
                UseCasesModule().module,
                SettingsModule().module,
                applicationsUiModule, //Needed to instantiate viewmodel with params
            )
        }
    ) { content() }
}
And also in build.gradle.kts configurations for app
Copy code
dependencies {
    debugImplementation(compose.uiTooling)
    add("kspCommonMainMetadata", libs.koin.ksp.compiler)
    add("kspJs", libs.koin.ksp.compiler)
    add("kspJvm", libs.koin.ksp.compiler)
    add("kspWasmJs", libs.koin.ksp.compiler)
    add("kspAndroid", libs.koin.ksp.compiler)
}

ksp {
    arg("KOIN_CONFIG_CHECK", "true")
    arg("KOIN_USE_COMPOSE_VIEWMODEL", "true")
    arg("KOIN_DEFAULT_MODULE", "true")
}

tasks.withType<KotlinCompilationTask<*>>().all {
    if(name != "kspCommonMainKotlinMetadata") {
        dependsOn("kspCommonMainKotlinMetadata")
    }
}

tasks.findByName("compileDebugKotlinAndroid")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileReleaseKotlinAndroid")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileKotlinJvm")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileKotlinJs")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileKotlinWasmJs")?.dependsOn("kspCommonMainKotlinMetadata")
And build.gradle.kts in shared module
Copy code
dependencies {
    implementation(libs.androidx.startup.runtime)
    ksp(libs.koin.ksp.compiler)
    add("kspCommonMainMetadata", libs.koin.ksp.compiler)
    add("kspJs", libs.koin.ksp.compiler)
    add("kspJvm", libs.koin.ksp.compiler)
    add("kspWasmJs", libs.koin.ksp.compiler)
    add("kspAndroid", libs.koin.ksp.compiler)
}

ksp {
    arg("KOIN_DEFAULT_MODULE", "true")
}

tasks.withType<KotlinCompilationTask<*>>().all {
    if (name != "kspCommonMainKotlinMetadata") {
        dependsOn("kspCommonMainKotlinMetadata")
    }
}

tasks.findByName("compileDebugKotlinAndroid")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileReleaseKotlinAndroid")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileKotlinJvm")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileKotlinJs")?.dependsOn("kspCommonMainKotlinMetadata")
tasks.findByName("compileKotlinWasmJs")?.dependsOn("kspCommonMainKotlinMetadata")
And usage of it is simple
Copy code
@Single
class UserRepository(
    private val json: Json = Json { ignoreUnknownKeys = true },
    private val settings: Settings,
) {
    fun saveUser(user: User) {
        settings.putString("user", json.encodeToString(user))
    }

    fun getUser(): User? =
        settings.getStringOrNull("user")?.let { json.decodeFromString(it) }
}
Am I missing something?
Added the repository as well in the question
k
can you try adding
@Provided
i.e
Copy code
@Single
class UserRepository(
    private val json: Json = Json { ignoreUnknownKeys = true },
    @Provided private val settings: Settings,
) {
   ....
}
r
Done, not sure why this annotation is needed honestly 😕 Now it's a different error:
Copy code
e: file:///Users/user/branches/Binshelve/composeApp/src/commonMain/kotlin/com/binshelve/ui/components/Koin.kt:20:32 None of the following candidates is applicable:
val DataModule.module: Module
val UIModule.module: Module
val UseCasesModule.module: Module
It is not able to find SettingsModule (Which is in shared gradle's module) Looks like annotations are not being well processed?
k
let me try come up with a repro, but if you have a ready project you can share
r
I can set it up one. On it
👍 1
So I've found the issue, it is just something in my configuration becuse in the basic project I was setting up to show the case it is working. Will investigate a bit more
k
okay
r
Thanks!!
koinscroll 1
Not sure what did I have wrong with the project, but finally it worked.
Thanks for the help
k
Glad to hear you solved it, welcome.