InsertKoinIO / koin-annotations

Koin Annotations - About Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform insert-koin.io
https://insert-koin.io
Apache License 2.0
165 stars 44 forks source link

Generate empty module on multiplatform for common code #8

Closed tristancaron closed 2 years ago

tristancaron commented 2 years ago

Describe the bug

When a module class is created in common code, but does not have any dependencies, the code fails to compile because .module does not exist.

To Reproduce

In common code

package com.my.package

import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module

@Module
@ComponentScan("com.my.package")
class MyPackageModule

In platform specific code

package com.my.package.usecase

import org.koin.core.annotation.Single

@Single
class GetUserUseCaseImpl : GetUserUseCase {
    override fun invoke() = "user"
}

Back in common

// Use Koin Generation
import org.koin.ksp.generated.*

// ...

startKoin {
    modules(MyPackageModule().module)
}

Then run code generation via ./gradlew kspCommonMainKotlinMetadata

The file default.kt is generated but empty (that's fine). The file MyPackageModuleGen.kt is missing, so common code is not aware of the extension .module.

When running the code directly on the targeted platform, the files needed for the platform are all generated correctly (MyPackageModuleGen.kt is created in the correct directory).

It does not prevent the code from compiling, but it stays red in common code.

Expected behavior

Generate usable code for common. Maybe use expect keyword?

Koin project used and used version (please complete the following information):

val koinVersion= "3.2.0-beta-1"
val koinKspVersion= "1.0.0-beta-1"
id("com.google.devtools.ksp") version "1.6.20-RC-1.0.4"

Additional moduleDefinition Add any other moduleDefinition about the problem here.

arnaudgiuliani commented 2 years ago

Need to check with KSP multiplatform generation part 👍

arnaudgiuliani commented 2 years ago

did you check https://github.com/InsertKoinIO/koin-annotations/issues/20 ?

arnaudgiuliani commented 2 years ago

KMP need special dependency setup

tristancaron commented 2 years ago

Thanks. We will take a look with the team and see if it resolves also issues with clashing generated code. (Like compiling for Android and code namespace issues)

tristancaron commented 2 years ago

Here how I define my KSP dependency (can be improved 🤫)

dependencies {
    add("kspCommonMainMetadata", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
    add("kspAndroid", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
    add("kspAndroidTest", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
    add("kspIosArm64", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
    add("kspIosArm64Test", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
    add("kspIosX64", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
    add("kspIosX64Test", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
    add("kspNative", "io.insert-koin:koin-ksp-compiler:$koinKspVersion")
}

Compiling for my targets work, even if the highlight is not working in the IDE image

We can get the highlight by running the script ./gradlew :shared:kspCommonMainKotlinMetadata and adding the following

val commonMain by getting {
  kotlin.srcDirs("build/generated/ksp/metadata/commonMain/kotlin")
}

But, if the module is empty in common code, it is it not generated. image

This is the module definition

package com.me.deviceInfo.di

import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.core.annotation.Single

@Module
@ComponentScan("com.me.deviceInfo")
class DeviceInfoModule

And how it looks like in the common code image

There is only interfaces that must get an implementation from the platforms.

So, in order to force Koin generating something, we did

package com.me.deviceInfo.di

import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.core.annotation.Single

class Force

@Module
@ComponentScan("com.me.deviceInfo")
class DeviceInfoModule {
    @Single
    fun force() = Force()
}

Then we get full highlight. image

But at this stage, the code does not compile anymore, because it's trying to include the path we added earlier.

e: /Users/me/AndroidStudioProjects/KotlinProject/shared/build/generated/ksp/android/androidDebug/kotlin/org/koin/ksp/generated/AuctionModuleGen.kt: (4, 5): Conflicting declarations: public val AuctionModuleModule: Module, public val AuctionModuleModule: Module

I am probably missing something with KSP?

arnaudgiuliani commented 2 years ago

Give a try with 1.0.2 and check your path config against Simple project: https://github.com/InsertKoinIO/hello-kmp/tree/annotations

Try to reactivate each path, one by one