GithubHelp home page GithubHelp logo

insertkoinio / koin-annotations Goto Github PK

View Code? Open in Web Editor NEW
140.0 3.0 37.0 863 KB

Koin Annotations - About Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform insert-koin.io

Home Page: https://insert-koin.io

License: Apache License 2.0

Kotlin 99.81% Shell 0.19%
kotlin android dependency-injection kotlin-multiplatform ksp

koin-annotations's Introduction

logo

Kotlin Apache 2 License Slack channel

What is KOIN Annotations?

Koin is a pragmatic lightweight dependency injection framework for Kotlin developers, developed by Kotzilla and open-source contributors.

Koin Annotations project brings annotation capacity to Koin projects, powered by Google KSP

Setup & Current Version

Here are the current available Koin projects versions:

Project Version
koin-annotations-bom Maven Central
koin-annotations Maven Central
koin-ksp-compiler Maven Central

Follow the Koin Annotations setup page for more details

Get started with Koin Tutorials ๐Ÿš€

You can find here tutorials to help you learn and get started with Koin framework:

Latest News & Resources ๐ŸŒ

Community ๐Ÿ’ฌ

Contributing ๐Ÿ› 

Want to help or share a proposal about Koin? problem on a specific feature?

  • Open an issue to explain the issue you want to solve Open an issue
  • Come talk on slack #koin-dev channel
  • After discussion to validate your ideas, you can open a PR or even a draft PR if the contribution is a big one Current PRs

Additional readings about basic setup: https://github.com/InsertKoinIO/koin/blob/master/CONTRIBUTING.adoc

Contributors

Thanks for your work โค๏ธ

Sponsorship โค๏ธ

Support this project by becoming a sponsor and be displayed on the offcial website. [Become a sponsor]

koin-annotations's People

Contributors

arnaudgiuliani avatar damianogiusti avatar erikvermunt-tomtom avatar gbourassa avatar ghasemdev avatar hoc081098 avatar hugolefrancois avatar jakoss avatar jbokman avatar nachtien avatar nohus avatar qdsfdhvh avatar stylianosgakis avatar ugurcany avatar wmontwe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

koin-annotations's Issues

Binding generation for module provide methods

Is your feature request related to a problem? Please describe.
Definition annotations can be applied to a module functions (provide methods), though they don't generate bind code block if method return type is an abstraction:

@Single(binds = [NetworkAdapter::class])
internal fun provideRetrofitAdapter(...): NetworkAdapter {
    return RetrofitAdapter(...)
}

class RetrofitAdapter(...) : NetworkAdapter

Generated code:

single(qualifier=null) { moduleInstance.provideRetrofitAdapter(...) }

Describe the solution you'd like
I expect that the specified return type (NetworkAdapter) will be automatically binded, e.g.:

single(qualifier=null) { moduleInstance.provideRetrofitAdapter(...) } bind(<classpath>.NetworkAdapter::class)

Android Quickstart app crash

Describe the bug
I'm having trouble running the quickstart android app on the Android emulator (tested API 29 and 30). When installing the app through Android Studio, it crashes on start up, the same goes when opening the application from the menu.

To Reproduce
Steps to reproduce the behavior:

  1. Pull the repository at latest main branch
  2. Install the Android application
  3. The app crashes

Here's the logcat error message:

2022-05-18 18:57:42.473 552-919/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.sample.koin/org.koin.sample.view.presenter.MySimpleActivity bnds=[841,578][1043,892]} from uid 10138
2022-05-18 18:57:42.473 552-919/system_process W/ActivityTaskManager: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.sample.koin/org.koin.sample.view.presenter.MySimpleActivity bnds=[841,578][1043,892] } from ProcessRecord{3f9afee 1051:com.google.android.apps.nexuslauncher/u0a138} (pid=1051, uid=10138) not exported from uid 10154
2022-05-18 18:57:42.478 1051-1051/com.google.android.apps.nexuslauncher E/BaseDraggingActivity: Unable to launch. tag=AppInfo(id=-1 type=APP container=all_apps targetComponent=ComponentInfo{org.sample.koin/org.koin.sample.view.presenter.MySimpleActivity} screen=-1 cell(-1,-1) span(1,1) minSpan(1,1) rank=0 user=UserHandle{0} title=Koin Sample App componentName=ComponentInfo{org.sample.koin/org.koin.sample.view.presenter.MySimpleActivity}) intent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.sample.koin/org.koin.sample.view.presenter.MySimpleActivity bnds=[841,578][1043,892] }
    java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.sample.koin/org.koin.sample.view.presenter.MySimpleActivity bnds=[841,578][1043,892] } from ProcessRecord{3f9afee 1051:com.google.android.apps.nexuslauncher/u0a138} (pid=1051, uid=10138) not exported from uid 10154
        at android.os.Parcel.createExceptionOrNull(Parcel.java:2373)
        at android.os.Parcel.createException(Parcel.java:2357)
        at android.os.Parcel.readException(Parcel.java:2340)
        at android.os.Parcel.readException(Parcel.java:2282)
        at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:3696)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1723)
        at android.app.Activity.startActivityForResult(Activity.java:5320)
        at com.android.launcher3.Launcher.startActivityForResult(SourceFile:2)
        at com.android.launcher3.BaseQuickstepLauncher.startActivityForResult(SourceFile:6)
        at android.app.Activity.startActivity(Activity.java:5660)
        at com.android.launcher3.BaseDraggingActivity.startActivitySafely(SourceFile:15)
        at com.android.launcher3.Launcher.startActivitySafely(SourceFile:7)
        at com.android.launcher3.uioverrides.QuickstepLauncher.startActivitySafely(SourceFile:3)
        at com.android.launcher3.touch.ItemClickHandler.startAppShortcutOrInfoActivity(SourceFile:15)
        at c.a.a.Y0.e.onClick(SourceFile:20)
        at android.view.View.performClick(View.java:7448)
        at android.view.View.performClickInternal(View.java:7425)
        at android.view.View.access$3600(View.java:810)
        at android.view.View$PerformClick.run(View.java:28305)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.wm.ActivityStackSupervisor.checkStartAnyActivityPermission(ActivityStackSupervisor.java:1032)
        at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:999)
        at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:669)
        at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1100)
        at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1072)

The error can be avoided if the app is launched through App Info:
Screenshot 2022-05-19 at 16 10 34

Expected behavior
The app doesn't crash

Build error when package name starts with id.***

Describe the bug
I created a project with the package name id.buaja.example. When I rebuild this project, an error occurs with the unresolved reference buaja.

This is because id is already used on :
org.koin.core.scope.Scope public final val id: ScopeID /* = String */
Gradle: io.insert-coins:coins-core-jvm:3.2.0-beta-1

that's why he got an error.

When I change the package name to com.buaja.example everything will work normally as it should.

To Reproduce
Steps to reproduce the behavior:

  1. Create project package name id.buaja.example
  2. Create inject with koin
  3. Rebuild project
  4. Error unresolved reference buaja

Expected behavior
What I hope is that when I make the package name id.buaja.example everything will be fine

Koin project used and used version (please complete the following information):
[e.g]: koin-core version 3.2.0-beta-1 , koin-annotation version 1.0.0-beta-2

Conflicting declarations error for multi variant Android module

Describe the bug
I have multiple variants in my android lib module. so the code below tries to include all generated files and creates conflict when I switch to a different variant (causing multiple identical generated module classes).

    libraryVariants.all { variant ->
        variant.sourceSets.java.each {
            it.srcDirs += "build/generated/ksp/${variant.name}/kotlin"
        }
    }

To Reproduce
Steps to reproduce the behavior:

  1. Have an Android library module with multiple build variants.
  2. Trigger module generation for a variant. (make the project)
  3. Switch to a different variant.
  4. Retrigger module generation again. (make the project again)
  5. You will see "Conflicting declarations..." error.

Expected behavior
The source dirs for a particular variant should only care about its own generated files, not the ones for other variants.

Koin project used and used version (please complete the following information):
koin 3.2, annotations 1.0.0-beta-2

Add support for iosSimulatorArm64

Adding support for iosSimulatorArm64 to allow dev with M1 Mac to compile a multiplateform projet on native Arm64 simulator.

Its should be as easy a the PR I her just submitted: #23

It will be really appreciated if you voulcould create a new release to include the small change.

ComponentScan as a list of packages

Is your feature request related to a problem? Please describe.
I have a multi-model project and the interfaces in project A don't bind in project B

Describe the solution you'd like
Provide an opportunity to specify the packages in ComponentScan annotation

ComponentScan as Arr

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Target Koin project
Specify the Koin project than will embed the feature.

[koin-annotations-js] library not available on Maven Central

Describe the bug
I started a new Kotlin Multiplatform project to tinker with this library in a multiplatform environment. After adding the
koin-annotations dependency to the main JS source set and syncing the project, I got a Gradle error indicating it could not find a JS variant of the library.

To Reproduce
Steps to reproduce the behavior:

  1. Add the koin-annotations dependency to the jsMain source set in build.gradle.kts of a Kotlin Multiplatform project.
kotlin {
    // ...
    sourceSets {
        // ...
        val jsMain by getting {
            dependencies {
                implementation(compose.web.core)
                implementation(compose.runtime)
                implementation("io.insert-koin:koin-annotations:$koinAnnotationsVersion")
                implementation("io.insert-koin:koin-core:$koinVersion")
            }
        }
    }
}

/** koin-ksp-compiler dependencies */
  1. Sync the Gradle project.
  2. See the error in the console.
> Could not resolve all dependencies for configuration ':jsCompileClasspath'.
   > Could not resolve io.insert-koin:koin-annotations:1.0.3.
     Required by:
         project :
      > No matching variant of io.insert-koin:koin-annotations:1.0.3 was found.

Expected behavior
I expected Gradle to be able to resolve the JS variant.

Koin project used and used version:
koin-annotations version 1.0.3
koin-core version 3.2.2
koin-ksp-compiler version 1.0.3

Generated code does not use getAll() for List type constructor parameters

Describe the bug
When a class's constructor takes a parameter of type List, the generated module specifies get() instead of getAll() when I am providing separate components for each type. When running the application, I get an error: I have not provided a component of type 'List'

To Reproduce
Run the following app:

interface MyInterface {
    fun doRun()
}

@Single
class MyInterfaceImpl1: MyInterface {
    override fun doRun() {
        println("Running first impl")
    }
}

@Single
class MyInterfaceImpl2: MyInterface {
    override fun doRun() {
        println("Running second impl")
    }
}

@Single
class MyInterfaceCollection(val myInterfaces: List<MyInterface>) {
    fun runAll() {
        myInterfaces.forEach(MyInterface::doRun)
    }
}

class MyComponent : KoinComponent {
    
    val collection: MyInterfaceCollection by inject

    fun run() {
        collection.runAll()
    }
}

fun main() {
    startKoin {
        defaultModule()
    }

    MyComponent().run()
}

The application throws an ExceptionInInitializerError caused by a NoBeanDefFoundException: No definition found for class: 'java.util.List'

Expected behavior
I expect all instances of implementation of MyInterface to be injected into MyInterfaceCollection.
Alternatively, if this cannot be supported out of the box or if this is deemed unwanted default behaviour, would it be possible to create an additional annotation to use on the parameter, to make it generate a getAll() call instead of a get() call?

Koin project used and used version (please complete the following information):
koin-core version 3.2.0
koin-annotations version 1.0.1

RecyclerView.Adapter not exists in autogenerated module files

I just switched to koin 3.2 & annots 1.0.0 versions. I'm using it in one of my android library modules. the issue is my recyclerview.adapter classes are not detected and not included in the autogenerated file.

@Factory
class ****Adapter(private val imageLoader: ImageLoader) :
    RecyclerView.Adapter<****Adapter.ItemViewHolder>()

This class contains inner classes for ViewHolders and an interface for click listeners. And as far as I understand, they might cause this issue. If I remove them from the adapter, everything works fine. Is this a known issue?

Gradle cannot resolve annotation library in Maven

Trying to sync my project with gradle, and I get:

Could not resolve io.insert-koin:koin-annotations:1.0.0-beta-2.

My setup is pretty basic:

dependencies {
    implementation "io.insert-koin:koin-core:3.2.0-beta-1"
    implementation "io.insert-koin:koin-annotations:1.0.0-beta-2"
    ksp "io.insert-koin:koin-ksp-compiler:1.0.0-beta-2"
}

Any ideas?

Multiple round processing is ignoring newly generated files

Describe the bug
I'm trying to add new feature to another ksp processing library that will automatically generate @Single or @Factory annotation for files that are generated by ksp. But the koin processor does not process those newly generated files and i think the reason is usage of flag codeGenerated here https://github.com/InsertKoinIO/koin-annotations/blob/main/compiler/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/BuilderProcessor.kt#L32. AFAIK this shouldn't be used like that, because even if the processor is done with all classes from my source it can be still called with new classes that are generated by another ksp processor. Is this flag even necessary? Ksp is automatically filtering classes that are processed. Looking at official example (https://github.com/google/ksp/blob/main/examples/playground/test-processor/src/main/kotlin/BuilderProcessor.kt) the processor should store the list of invalid classes, process the valid ones and then result list of invalid ones so it can be called later with of those classes. I think i can do a PR with that if you're open to my suggestion.

PS. Do you have tests for generated code?

To Reproduce
Steps to reproduce the behavior:

  1. Create an ksp processor that generates class with @Single annotation
  2. Setup a koin project that tries to use that class by AppModule().module
  3. Project does not comple, module with the configuration for generated class does not get generated

Project that can be reproduced on: https://github.com/jakoss/kmapper/blob/feature/di-integration/examples/koin/src/main/kotlin/com/syouth/kmapper/koin/Main.kt

Expected behavior
Koin should properly generate injection configuration for code that is generated by another ksp processors

Koin project used and used version (please complete the following information):
koin-ksp-processor version 1.1.0

The Library incorrectly generates files for a multi-platform project

Describe the bug
Highlighting in Android Studio doesn't work when using generated resources in a multi-platform project

To Reproduce
Steps to reproduce the behavior:

  1. Add koin-annotations to a multiplatform project.
  2. Add all necessary modules.
  3. Try to register modules.
  4. See error

Expected behavior
Highlighting in Android Studio works as expected.

Actual behavior
Highlighting in Android Studio doesn't work as expected.

This happens because when I add generated platform folders to srcDir, Android Studio still expects the common path:
I add kotlin.srcDir("build/generated/ksp/android/androidDebug/kotlin") for android
and kotlin.srcDir("build/generated/ksp/desktop/desktopMain/kotlin") for desktop

And Adnroid studio sees them:
image

But still doesn't see generated code from common code:
image

Important
I can build the project, this issue affects only visual representation.

koin-core version 3.2.0-beta-1
koin-annotations version 1.0.0-beta-2

Additional
Sample code: https://github.com/DoTheMonkeyBusiness/koinAnnotationIssue/tree/multiplatform_exception

Keep up to date with Kotlin/Ksp versions

Is your feature request related to a problem? Please describe.
As far as I know, we need to match all ksp plugins with a given Kotlin version and there were new releases of kotlin and ksp in the last few months that would make the usage of this project a bit risky or incompatible.

Describe the solution you'd like
Would it be possible to keep this project updated with the current releases of Kotlin and Ksp? At least with the stable releases?

The module is not generated by the Koin Annotations

Describe the bug
The module is not generated by the Koin Annotations

To Reproduce
Steps to reproduce the behavior:

I'm trying to add a module for the coroutine dispatcher

`@Module
class CoroutinesDispatcherModule {
@single
@nAmed("DefaultDispatcher")
fun defaultDispatcher(): CoroutineDispatcher = Dispatchers.Default

@Single
@Named("IoDispatcher")
fun ioDispatcher(): CoroutineDispatcher = Dispatchers.IO

@Single
@Named("MainDispatcher")
fun mainDispatcher(): CoroutineDispatcher = Dispatchers.Main

}`

Expected behavior
How can the coroutine dispatcher module be generated

Koin project used and used version (please complete the following information):
[e.g]: koin_version = '3.2.0-beta-1' koin_ksp_version = "1.0.0-beta-1" ksp = '1.6.10-1.0.4'

I make a call like this:

@single
class MealDataSourceImpl(
private val mealService: MealService,
@nAmed("ioDispatcher") private val coroutineDispatcher: CoroutineDispatcher
)

Allow top-level functions to be annotated

Is your feature request related to a problem? Please describe.

I have many files that define HttpClients like so:

// FooHttpClient.kt
fun buildFooHttpClient(config: FooConfig) = HttpClient(CIO) { /* ... */ }

// BarHttpClient.kt
fun buildBarHttpClient(config: BarConfig) = HttpClient(CIO) { /* ... */ }

// ...etc

...and a module like so:

val httpClientsModule = module {
	singleOf(::buildFooHttpClient) { named("Foo") }
	singleOf(::buildBarHttpClient) { named("Bar") }
	// ...etc
}

I am porting the codebase to use Koin annotations.

Describe the solution you'd like

Analogous to how class definitions work, it seemed logical that I would just annotate the builder functions with @Single(binds = [HttpClient::class]) @Named("Foo"), and then @Module @ComponentScan(...) class HttpClientsModule would pick them up.

This is not the case. Annotating free standing functions generates no code.

Describe alternatives you've considered

I could put all the builder functions as methods to a single class and annotate it as @Module, which works but requires me to keep all the definitions in a single file. There is no way to split that class without involving a lot of boilerplate code, the very kind I try to avoid by using koin-annotations.

Target Koin project
koin-annotations

Unresolved reference: StringQualifier

Describe the bug
Unresolved reference: StringQualifier when using @Named for constructor parameter in class marked with @Single.

To Reproduce
Steps to reproduce the behavior:

  1. Setup a KMP project
  2. Mark a class with @Single
  3. Mark a constructor parameter with @Named
  4. Build
  5. See error

Expected behavior
Successful build

Koin project used and used version (please complete the following information):
koin-core version 3.2.0-beta-1
koin-ksp 1.0.0-beta-1
ksp version 1.6.10-1.0.4

Unresolved Reference org.koin.ksp

Describe the bug
Trying to configure Koin Annotations in my android app per the documentation and when I try to find the import import org.koin.ksp.generated.* to use defaultModule() when starting koin it does not recognize ksp.

My project build.gradle looks like this

buildscript {
    ext.retrofit_version = '2.9.0'
    ext.kotlin_version = '1.7.10'
    ext.moshi_version = '1.14.0'
    ext.okhttp_version = '4.9.0'

    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.4'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

plugins {
    id 'com.android.application' version '7.3.0' apply false
    id 'com.android.library' version '7.3.0' apply false
    id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
    id "com.google.devtools.ksp" version "1.7.10-1.0.6" apply false
}

My app build.gradle looks like this

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-parcelize'
    id 'com.google.devtools.ksp'
}

android {
    namespace 'com.my.app'
    compileSdk 33

    defaultConfig {
        applicationId "com.my.app"
        minSdk 25
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            signingConfig signingConfigs.config
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            autoIncrementBuildNumber
            versionNameSuffix "." + versionBuild
        }
        debug {
            signingConfig signingConfigs.config
            autoIncrementBuildNumber
            versionNameSuffix "." + versionBuild
        }
    }
    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }
    buildFeatures {
        viewBinding true
    }
    lintOptions {
        abortOnError false
    }
    applicationVariants.all { variant ->
        variant.outputs.all {
            outputFileName = "Player_${defaultConfig.versionName}.${versionBuild}.apk"
        }
    }
    applicationVariants.configureEach { variant ->
        kotlin.sourceSets {
            getByName(name) {
                kotlin.srcDir("build/generated/ksp/${variant.name}/kotlin")
            }
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.8.0-alpha01'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.palette:palette-ktx:1.0.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
    implementation 'androidx.activity:activity-ktx:1.6.0'
    implementation 'androidx.fragment:fragment-ktx:1.5.3'
    implementation "androidx.work:work-runtime-ktx:2.7.1"

    implementation "io.insert-koin:koin-android:3.2.2"
    implementation "io.insert-koin:koin-android-compat:3.2.2"
    implementation "io.insert-koin:koin-annotations:1.0.3"
    implementation "io.insert-koin:koin-androidx-workmanager:3.2.2"
    ksp "io.insert-koin:koin-ksp-compiler:1.0.3"

    implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
    implementation "com.squareup.okhttp3:okhttp-urlconnection:$okhttp_version"
    implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"

    implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
    implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
    implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
    ksp "com.squareup.moshi:moshi-kotlin-codegen:1.14.0"

    implementation "org.jetbrains.kotlin:kotlin-jdk-annotations:1.0.0"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'

    implementation 'com.facebook.android:facebook-core:13.0.0'
    implementation 'com.facebook.android:facebook-login:13.0.0'

    implementation("io.coil-kt:coil:1.4.0")
    implementation("io.coil-kt:coil-gif:1.4.0")

    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'

    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

Expected behavior
The import to be found

koin-ksp-compiler 1.0.3

Native compilation not working since 1.0.1

Describe the bug
I have kotlin multi-platform project, in which in only have koin-related annotations in my common module. I'm using the kspCommonMainMetadata approach to generate module code.

Since version 1.0.1 of koin-annotations, attempting to compile with a native target (for instance iosArm64), I get a compilation error on the generated code:

[someModuleName].kt: (1, 7): Unresolved reference: JvmName
[someModuleName].kt: (2, 7): Unresolved reference: JvmMultifileClass

Since this commit (72c3d6f), there is now this header at the top of the module file:

@file:JvmName("${genName}Gen")
@file:JvmMultifileClass

But these annotations are not imported. When using java-based targets (ie. Android), this seems to work ok. But not on native targets.

Expected behavior
JvmName and JvmMultifileClass should probably be imported in the generated code.

Koin project used and used version (please complete the following information):
koin-core version 3.2.0
koin-annotations version 1.0.1

@ComponentScan does not work in multimodules project.

Describe the bug
@componentscan configured for given package only scans package in current gradle module. Other gradle modules with same package name are not scanned.

To Reproduce
Steps to reproduce the behavior:

Setup a KMP project
Create some module and mark it as @componentscan(value ="packageName")
Create some class X in other gradle module in package "packageName" and mark as @single
Try to inject the class X somewhere
Build
See error
Expected behavior
It should be possible to inject the class.

Koin project used and used version (please complete the following information):
koin-core version 3.2.0-beta-1
koin-ksp 1.0.0-beta-1
ksp version 1.6.10-1.0.2

Required Android ApplicationContext and ActivityContext Injection support

I'm looking injecting the context as parameter inside the module method definitions. could you please add a support like Hilt annotations ?

  1. ApplicaitonContext
  2. ActivityContext.

@Module
class DatabaseModule {
    @Single
    fun provideBoxStore(context: Context): BoxStore {
        var boxStore = MyObjectBox.builder().androidContext(context).build()
        if (BuildConfig.DEBUG) {
            val started: Boolean = Admin(boxStore).start(context)
        }
        return boxStore
}

module type bug

Describe the bug
type must be specified when a module field is in a module

To Reproduce
Steps to reproduce the behavior:

  1. not specify a module type in the module field in a module

Expected behavior
module class must be generated

Koin project used and used version (please complete the following information):
core version 3.2.0
annotations version 1.0.1

video:
https://imgur.com/USbXqjq

Upgrade koin from 2.0.1 to 3.2.0

Describe the bug
Error after upgrading koin

No definition found for class:MyUseCase & qualifier: MyUseCase

Koin project used and used version (please complete the following information):
After the upgrade we are using:
io.insert-koin:koin-android:3.2.0
io.insert-koin:koin-core:3.2.0
io.insert-koin:koin-test:3.2.0

Previously it was:
org.koin:koin-android-viewmodel:2.0.1
org.insert-koin:koin-android:2.0.1
org.insert-koin:koin-core:2.0.1
org.insert-koin:koin-test:2.0.1

To Reproduce
In our previous implementation we used it it this way:
single<BaseUseCase<Int, String>>(named(MY_USE_CASE)) { MyUseCase(get(), get()) }

After the update we changed to this way:
single{MyUseCase(get(), get()) } bind BaseUseCase::class

Module can't generate ModuleGen file on specific case.

Describe the bug
When I declare same named two Module class in different packages,
koin-ksp-compiler failed to task.

To Reproduce
Steps to reproduce the behavior:

  1. declare two Module class in different packages with same name.

foo/DatabaseConfig.kt

package foo

@Module
class DatabaseConfig {

    @Single
    @Named("mysql")
    fun mysql(): String = "this is mysql"
}

bar/DatabaseConfig.kt

package bar

@Module
class DatabaseConfig {
    @Single
    @Named("mariadb")
    fun mariadb(): String = "this is mariadb"
}
  1. build
  2. kspKotlin task failed.
  3. See error
[ksp] kotlin.io.FileAlreadyExistsException: [location]
        at com.google.devtools.ksp.processing.impl.CodeGeneratorImpl.createNewFile(CodeGeneratorImpl.kt:75)
	at com.google.devtools.ksp.processing.CodeGenerator$DefaultImpls.createNewFile$default(CodeGenerator.kt:59)
	at org.koin.compiler.generator.KoinGeneratorKt.getFile(KoinGenerator.kt:103)
	at org.koin.compiler.generator.KoinGeneratorKt.getFile$default(KoinGenerator.kt:103)
	at org.koin.compiler.generator.KoinGenerator.generateModule(KoinGenerator.kt:68)
	at org.koin.compiler.generator.KoinGenerator.generateModules(KoinGenerator.kt:49)
        ...

Expected behavior
Generate Two Module files successfully.

Koin project used and used version (please complete the following information):
koin-core: 3.2.0-beta-1
koin-annotations: 1.0.0-beta-2

Additional moduleDefinition
Add any other moduleDefinition about the problem here.

Imports not properly formatted in generated file

I'm trying to annotate a ViewModel like this with both @KoinViewModel and @scope

@KoinViewModel
@Scope(ExampleFragment::class)
class ExampleViewModel: ViewModel()

The project has already been using koin-android 3.1.5 successfully. I have done no other change in the code except the ones mentioned in the readme.

The imports in the resulting generated code are not properly formatted:

package org.koin.ksp.generated

import org.koin.core.KoinApplication
import org.koin.core.module.Module
import org.koin.dsl.*import org.koin.core.qualifier.StringQualifierimport org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.androidx.viewmodel.dsl.viewModel
fun KoinApplication.defaultModule() = modules(defaultModule)
val defaultModule = module {
	scope<com.example.ExampleFragment> {
			viewModel(qualifier=null) { com.example.ExampleViewModel() }
	}
}

Koin project used and used version:
koin-android version 3.2.0-beta-1
koin-annotations version 1.0.0-beta-1

Gradle fails with "Overload resolution ambiguity" errors

Intro
I migrated to Koin 3.2.0 (Koin annotation 1.0.0-beta-2) and started rewriting the code with annotations. The project uses several product flavors. When you run a Gradle, then it displays Overload resolution ambiguity and Conflicting declarations errors for each Build variant, which prevents from getting a working build.
I use ./gradlew build --warning-mode all command for getting error details (see logs attachment).

Screenshot 2022-05-27 at 10 47 35

This is interfering with the normal build process in App Center. How can this be fixed? Thanks

Error

> Task :app:compileProdReleaseKotlin
Execution optimizations have been disabled for task ':app:compileProdReleaseKotlin' to ensure correctness due to the following reasons:
  - Gradle detected a problem with the following location: '/Users/admin/projects/test-koin/app/build/generated/ksp/dev6Debug/kotlin'. Reason: Task ':app:compileProdReleaseKotlin' uses this output of task ':app:kspDev6DebugKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: '/Users/admin/projects/test-koin/app/build/generated/ksp/dev6Release/kotlin'. Reason: Task ':app:compileProdReleaseKotlin' uses this output of task ':app:kspDev6ReleaseKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
  - Gradle detected a problem with the following location: '/Users/admin/projects/test-koin/app/build/generated/ksp/prodDebug/kotlin'. Reason: Task ':app:compileProdReleaseKotlin' uses this output of task ':app:kspProdDebugKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
Gradle detected a problem with the following location: '/Users/admin/projects/test-koin/app/build/generated/ksp/dev6Debug/kotlin'. Reason: Task ':app:compileProdReleaseKotlin' uses this output of task ':app:kspDev6DebugKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem. This behaviour has been deprecated and is scheduled to be removed in Gradle 8.0. Execution optimizations are disabled to ensure correctness. See https://docs.gradle.org/7.4.2/userguide/more_about_tasks.html#sec:up_to_date_checks for more details.
Gradle detected a problem with the following location: '/Users/admin/projects/test-koin/app/build/generated/ksp/dev6Release/kotlin'. Reason: Task ':app:compileProdReleaseKotlin' uses this output of task ':app:kspDev6ReleaseKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem. This behaviour has been deprecated and is scheduled to be removed in Gradle 8.0. Execution optimizations are disabled to ensure correctness. See https://docs.gradle.org/7.4.2/userguide/more_about_tasks.html#sec:up_to_date_checks for more details.
Gradle detected a problem with the following location: '/Users/admin/projects/test-koin/app/build/generated/ksp/prodDebug/kotlin'. Reason: Task ':app:compileProdReleaseKotlin' uses this output of task ':app:kspProdDebugKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.4.2/userguide/validation_problems.html#implicit_dependency for more details about this problem. This behaviour has been deprecated and is scheduled to be removed in Gradle 8.0. Execution optimizations are disabled to ensure correctness. See https://docs.gradle.org/7.4.2/userguide/more_about_tasks.html#sec:up_to_date_checks for more details.
e: /Users/admin/projects/test-koin/app/build/generated/ksp/dev6Debug/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (4, 5): Conflicting declarations: public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/dev6Debug/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 42): Conflicting declarations: public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/dev6Debug/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 87): Overload resolution ambiguity: 
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
e: /Users/admin/projects/test-koin/app/build/generated/ksp/dev6Release/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (4, 5): Conflicting declarations: public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/dev6Release/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 42): Conflicting declarations: public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/dev6Release/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 87): Overload resolution ambiguity: 
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
e: /Users/admin/projects/test-koin/app/build/generated/ksp/prodDebug/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (4, 5): Conflicting declarations: public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/prodDebug/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 42): Conflicting declarations: public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/prodDebug/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 87): Overload resolution ambiguity: 
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
e: /Users/admin/projects/test-koin/app/build/generated/ksp/prodRelease/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (4, 5): Conflicting declarations: public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module, public val AppModuleModule: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/prodRelease/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 42): Conflicting declarations: public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module, public val AppModule.module: Module
e: /Users/admin/projects/test-koin/app/build/generated/ksp/prodRelease/kotlin/org/koin/ksp/generated/AppModuleGen.kt: (61, 87): Overload resolution ambiguity: 
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModuleModule: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
e: /Users/admin/projects/test-koin/app/src/main/java/com/mysite/core/App.kt: (56, 33): Overload resolution ambiguity: 
public val AppModule.module: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModule.module: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModule.module: Module defined in org.koin.ksp.generated in file AppModuleGen.kt
public val AppModule.module: Module defined in org.koin.ksp.generated in file AppModuleGen.kt

> Task :app:compileProdReleaseKotlin FAILED

build.gradle (root level)

buildscript {
    ext {
        kotlin_version = '1.6.21'
        nav_version = '2.5.0-beta01'
        input_mask_version = '6.1.0'
    }
    repositories {
        google()
        mavenCentral()
        maven { url "https://jitpack.io" }
    }
    dependencies {
        classpath 'com.google.gms:google-services:4.3.10'
        classpath 'com.android.tools.build:gradle:7.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://jitpack.io" }
    }

    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
        kotlinOptions {
            freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn'
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle (app level)

plugins {
    id 'com.android.application'
    id 'com.google.gms.google-services'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'androidx.navigation.safeargs'
    id 'kotlin-parcelize'
    id 'com.google.devtools.ksp' version "1.6.21-1.0.5"
}

android {
    compileSdkVersion 31
    buildToolsVersion '31.0.0'
    defaultConfig {
        applicationId "com.mysite"
        minSdkVersion 26
        targetSdkVersion 31
        versionCode 1
        versionName "2.1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
        manifestPlaceholders = [appAuthRedirectScheme: 'com.mysite']
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    flavorDimensions "environment"
    productFlavors {
        dev6 {
            dimension "environment"
            versionNameSuffix "-dev6"
        }
        prod {
            dimension "environment"
            versionNameSuffix "-prod"
        }
    }
    buildFeatures {
        viewBinding true
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = '11'
    }

    // For KSP
    applicationVariants.all { variant ->
        variant.sourceSets.java.each {
            it.srcDirs += "build/generated/ksp/${variant.name}/kotlin"
        }
    }
}

dependencies {
    // Kotlin
    implementation 'androidx.core:core-ktx:1.7.0'
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

    // Core
    implementation 'androidx.appcompat:appcompat:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.activity:activity-ktx:1.4.0'
    implementation 'androidx.fragment:fragment-ktx:1.4.0'
    implementation 'androidx.preference:preference-ktx:1.1.1'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'

    // Navigation
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
    implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

    // Lifecycle
    def lifecycle_version = '2.4.0'
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // Coroutines
    def coroutines_version = '1.6.1'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
    
    // Ktor
    def ktor_version = '1.6.6'
    implementation "io.ktor:ktor-client-core:$ktor_version"
    implementation "io.ktor:ktor-client-cio:$ktor_version"
    implementation "io.ktor:ktor-client-gson:$ktor_version"
    implementation "io.ktor:ktor-client-logging-jvm:$ktor_version"

    // Koin
    def koin_version = '3.2.0'
    def koin_annotations_version = '1.0.0-beta-2'
    implementation "io.insert-koin:koin-android:$koin_version"
    implementation "io.insert-koin:koin-androidx-navigation:$koin_version"
    implementation "io.insert-koin:koin-annotations:$koin_annotations_version"
    ksp "io.insert-koin:koin-ksp-compiler:$koin_annotations_version"

    // Room
    def room_version = '2.4.0'
    implementation "androidx.room:room-runtime:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
    kapt "androidx.room:room-compiler:$room_version"

    // Timber
    implementation 'com.jakewharton.timber:timber:5.0.1'

    // Testing
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

App.kt

import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import org.koin.core.logger.Level
import org.koin.ksp.generated.module

class App : Application() {

    override fun onCreate() {
        super.onCreate()
        initKoin()
    }

    private fun initKoin() {
        startKoin {
            androidContext(this@App)
            modules(AppModule().module)
        }
    }
}

AppModule.kt

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

@Module
@ComponentScan("com.mysite")
class AppModule

logs.zip

A class that extends an interface on a different Gradle module won't generate proper binds

Describe the bug
If you use a @Factory or @Single annotation on a class that extends an interface in another Gradle module, the generated code won't include the proper bind to the interface. Even manually adding the class to the binds annotation will fail.

To Reproduce
Steps to reproduce the behavior:

  1. Create a project with two modules (I tried with an Android app and a kotlin library)
  2. Create an interface in the second module
  3. Create a class implementing that interface in the first module
  4. Annotate the class with @Single or @Factory

You can try it in this repository, for example with this class. You will need a TheMovieDb api key though.

Expected behavior
Binds should be properly generated, both automatically and manually.

Koin project used and used version (please complete the following information):
koin-annotations 1.0.0-beta-1

Koin annotations has a dependency on junit

Describe the bug
Unnecessary dependency on junit in io.insert-koin:koin-annotations:1.0.0-beta-1

To Reproduce
This is causing a conflict in my local project, but you can see it defined in the gradle file

Expected behavior
Non-test libraries should not take a dependency on junit

Koin project used and used version (please complete the following information):
io.insert-koin:koin-annotations:1.0.0-beta-1

injection of android navigationGraph args

Is your feature request related to a problem? Please describe.
I would like to use koin-annotations to inject ViewModel with android navigationGraph parameters.

Currently I inject it without annotations:

viewModel { (args: MainFragmentArgs) -> MainViewModel(MainViewState(args), get()) }

main_navigation_graph.xml

<fragment
        android:id="@+id/fragment_main"
        android:name="my.app.MainFragment"
        tools:layout="@layout/fragment_main">

        <argument
            android:name="data"
            app:argType="string" />

    </fragment>
class MainFragment : ... {
    override val viewModel: MainViewModel by viewModel {
        parametersOf(MainFragmentArgs.fromBundle(requireArguments()))
    }
}

interface ViewState

class MainViewState(args: MainFragmentArgs) : ViewState {
    val data = args.data
}

abstract class BaseViewModel<VS : ViewState> : ViewModel(), CoroutineScopeOwner, DefaultLifecycleObserver, KoinComponent {}

class MainViewModel(
    override val viewState: MainViewState,
    private val repository: MainRepository
) : BaseViewModel<MainViewState>() {
...
}

Describe the solution you'd like
With annotation processor I would like to inject Navigation graph args, but I think, that's not possible now, because classes are not annotated by Koin.

@Factory
class MainViewState(...

@KoinViewModel
class MainViewModel(...

So when I use it with this annotations I get:

org.koin.core.error.InstanceCreationException: Could not create instance for [Factory:'my.app.MainViewModel',binds:my.app.BaseeViewModel]
Caused by: org.koin.core.error.NoBeanDefFoundException: |- No definition found for class:'my.app.MainViewState'. Check your definitions!

because it can't inject val args: MainFragmentArgs I think, because it's added to viewModel manually now by viewModel { (args: MainFragmentArgs) ->

I tried to use:

@Factory(binds = [MainFragmentArgs::class])
class MainViewState(

and

class MainViewState(
    @InjectedParam val args: MainFragmentArgs,

but it's not annotated by Koin, so I think, that's still not possible use it in this way.

Wrong import path for a nested class

Describe the bug
Hello together, I really like the new koin annotation framework. Thanks for creating this library. Unfortunately, I am not able to generate the correct import path for a nested abstract class. Koin does not add the outer class to the import path. I guess the example below is a better way to understand the problem.

To Reproduce
Steps to reproduce the behavior:
1.
Bildschirmfoto 2022-07-02 um 19 49 53
2.
Bildschirmfoto 2022-07-02 um 19 50 19

Expected behavior
Bildschirmfoto 2022-07-02 um 20 01 12

Koin project used and used version (please complete the following information):
compileOnly("io.insert-koin:koin-annotations:1.0.1")

Doesn't work with explicit API

If a module is generated and the module uses explicitAPI, koin won't generate an explicit API module and it will throw compilation errors. Many developers use this for library development so that they clearly mark what is internal or public.

kotlinOptions { freeCompilerArgs = freeCompilerArgs + "-Xexplicit-api=strict" }

How to provide methods in Koin 3.2.0?

I migrated to Koin 3.2.0 and started rewriting the code with annotations.

I have a Database file with some methods:

@Database(entities = [Contact::class, Location::class], version = 1, exportSchema = false)
abstract class MyDatabase : RoomDatabase() {
    abstract fun contactsDao(): ContactsDao
    abstract fun locationsDao(): LocationsDao
}

fun provideDatabase(application: Application): MyDatabase {
    return Room.databaseBuilder(application, MyDatabase::class.java, "my_database")
        .fallbackToDestructiveMigration()
        .build()
}

fun provideContactsDao(db: MyDatabase): ContactsDao {
    return db.contactsDao()
}

fun provideLocationsDao(db: MyDatabase): LocationsDao {
    return db.locationsDao()
}

In the Modules for Koin 2.x:, I could provide methods in this way:

val databaseModule = module {
    single { provideDatabase(androidApplication()) }
    single { provideContactsDao(get()) }
    single { provideLocationsDao(get()) }
}

But this way doesn't work:

@Single
fun provideDatabase(application: Application): MyDatabase {
    return Room.databaseBuilder(application, MyDatabase::class.java, "my_database")
        .fallbackToDestructiveMigration()
        .build()
}

I didn't find in the documentation how to provide methods through annotations. Is it possible to do this with annotations or do I need to use a workaround?

KoinViewModel is not working as expected

I just switched to koin 3.2 & annots 1.0.0 versions. I'm using it in one of my android library modules. the issue is my viewmodel classes which are annotated with @KoinViewModel are defined as "factory" in autogenerated module files:

val com_******_presentation_stock_Stock = module {
   factory(qualifier=null) { com.******.presentation.stock.StockViewModel(get(),get(),get(),get(),get(),get(),get()) } binds(arrayOf(androidx.lifecycle.ViewModel::class,androidx.lifecycle.DefaultLifecycleObserver::class,com.******.presentation.util.ViewStateHolder::class))
}

Support for JavaScript

Using the project for a multiplatform library, it seems that the support for JavaScript does not exist.

Looking at the artifacts available, I can see that indeed it is not present.

Is there support planned for this target? Is there a limitation from KSP?

Unresolved reference org.koin.ksp.generated.* KMP project

Describe the bug
Following the documentation results in a Unresolved reference org.koin.ksp.generated.* in a KMP project

The only way I was able to fix it is by adding

dependencies {
    add("kspMetadata", KmpLibrary.koinCompiler)
}

and manually running the kspKotlinMetadata gradle task.

To Reproduce
Steps to reproduce the behavior:

  1. Create a KMP project
  2. Add koin annotations
  3. Try to build the shared module

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

  • koin-annotations version 1.0.0-beta-2
  • koin-ksp-compiler version 1.0.0-beta-2

Additional moduleDefinition
Using

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

Inheritance with single not work with annotation

Current state:

single { ARepository(get()) }
single { AChildRepository(get(), get()) }

What I expected with annotations module:

@Single
open class ARepository(
    private val remoteService: RemoteService
) {}

@Single
class AChildRepository(
    private val remoteService: RemoteService,
    private val dao: XDao
): ARepository(remoteService) {}

But it fails with

Caused by: org.koin.core.error.DefinitionOverrideException: Already existing definition for [Singleton:'...
at org.koin.core.module.ModuleKt.overrideError(Module.kt:197)
        at org.koin.core.module.Module.saveMapping(Module.kt:138)
        at org.koin.core.module.Module.saveMapping$default(Module.kt:136)
        at org.koin.core.module.Module.indexPrimaryType(Module.kt:116)

Dependency resolve problem from another module

I'm using the annotations to implement a clean architecture multi-module Android application. In this setting, I have two modules - DomainModule and DataModule. data module includes domain module (domain module cannot access directly data module). I have an interface in domain module and its implementation is declared in data module. Now I face the issue, the implementation cannot resolve in the domain module. I have experience with the previous version of Koin too, there was not such a problem. I guess, resolved modules are not binded at the top level (in my case, global application class)

  • domainModule

    • RepoInterface
  • dataModule

    • RepoImplementation

To Reproduce
Steps to reproduce the behavior:

  1. Create 2 gradle modules: data and domain
  2. Inluce domain into data
  3. Create an interface in domain
  4. Create an implementation of the previous interface in data
  5. Try to access this implementation in domain module

Expected behavior
Implementation of interface from another module should be resolved, as we are binding them at the top level: modules(listOf(DataModule().module, DomainModule().module))

Koin project used and used version:

koinVersion = "3.2.0-beta-1"
koinKspVersion = "1.6.20-1.0.5"
koinAnnotationsVersion = "1.0.0-beta-1"


implementation "io.insert-koin:koin-core:$koinVersion"
implementation "io.insert-koin:koin-annotations:$koinAnnotationsVersion"
ksp "io.insert-koin:koin-ksp-compiler:$koinAnnotationsVersion"

Adding a new annotation for cross injection

I have classes:

class ComposeHandler(private val postId: String)
class ComposeViewModel(private val composeHandler: ComposeHandler): ViewModel

Before using Koin Annotation, I registered Koin module like this:

    factory { params -> 
        ComposeHandler(params.get()) 
    }

    viewModel { parameters ->
        ComposeViewModel(
            composeHandler = get<ComposeHandler> { parameters },
        )
    }

I tried to adding annotation for both classes

@Factory
class ComposeHandler(
    @InjectedParam private val postId: String
)
@KoinViewModel
class ComposeViewModel(private val composeHandler: ComposeHandler): ViewModel

And gen code would be like this:

factory(qualifier=null) { params -> my.package.ComposeHandler(params.get()) }
viewModel(qualifier=null) { my.packgage.ComposeViewModel(get()) }

According to gen code by Koin Annotation, I can't pass parameters to ComposeHandler.
So I can't use annotation in this case
I think adding a new annotation can solve this problem

@KoinViewModel
class ComposeViewModel(
   @NewAnnotation private val composeHandler: ComposeHandler
): ViewModel

and gen code is

viewModel(qualifier=null) { params -> my.packgage.ComposeViewModel(get { parametersOf(params) }) }

Koin project used and used version (please complete the following information):
koin-core version 3.2.0
koin-annotation 1.0.1
ksp version 1.6.10-1.0.4

Impossible to implement sealed interface.

Describe the bug
Ksp generator removes sealed interface from path.

To Reproduce
Steps to reproduce the behavior:

  1. Create sealed Interface:
sealed interface SealedInterface {

    interface InternalInterface : SealedInterface
}
  1. Implement it:
@Single
class SampleClass : SealedInterface.InternalInterface {
}
  1. Build project
  2. See error

Expected behavior
ksp must generate fulls path to SealedInterface.InternalInterface

Actual behavior
ksp removes SealedInterface from path to interface

Generated file:

val CommonModuleModule = module {
	single(qualifier=null) { com.example.koinissue.common.SampleClass() } bind(com.example.koinissue.common.InternalInterface::class)
}
val com.example.koinissue.common.koin.CommonModule.module : org.koin.core.module.Module get() = CommonModuleModule

koin-core version 3.2.0-beta-1
koin-annotations version 1.0.0-beta-2

Additional
Sample code: https://github.com/DoTheMonkeyBusiness/koinAnnotationIssue/tree/Sealed_interface_issue

Impossible to include koin module from another gradle module

Describe the bug
ksp doesn generate path to koin module from another gradle module when I try to include it into main koin module.

To Reproduce

  1. Create gradle module and plug it into main gradle module.
  2. Try to include koin module from submodule into main koin module:
@Module(includes = [SubmoduleModule::class])
@ComponentScan("com.example.koinissue.common")
class CommonModule
  1. Build project
  2. See error

Expected behavior
Ksp generates path to SubmoduleModule.

Actual behavior
Ksp doesn't generate path to SubmoduleModule and throws an exception.

Generated file:

val CommonModuleModule = module {
	includes(.SubmoduleModule().module)
	single(qualifier=null) { com.example.koinissue.common.SampleClass() } 
}
val com.example.koinissue.common.koin.CommonModule.module : org.koin.core.module.Module get() = CommonModuleModule

koin-core version 3.2.0-beta-1
koin-annotations version 1.0.0-beta-2

Additional
Sample code: https://github.com/DoTheMonkeyBusiness/koinAnnotationIssue/tree/Submodule_issue

KSP code generation bug

Description
Generated Koin module doesn't respect nested interfaces (parents of nested interfaces)

To Reproduce
Steps to reproduce the behavior:

  1. Declare nested interface (see code below - SymptomRarity.Transformer)
  2. Create nested interface implementation (see code below - SymptomRarityToScoreTransformer)
  3. Mark interface implementation with @Factory annotation
  4. Create module class marked with @Module and @ComponentScan("...") annotations
  5. Build project
  6. See unresolved reference error in generated file - interface implementation binding doesn't include parent interface into the full class path (see below)

Koin project used and used version (please complete the following information):
koin-core version 3.2.0
koin-annotations version 1.0.1

Notes
Nested interface binding path is also incorrect if interface parent is abstract class

Nested interface declaration

interface SymptomRarity {

    fun <T> transform(transformer: Transformer<T>): T

    interface Transformer<T> {
        ...
    }
}

Nested interface implementation

@Factory
class SymptomRarityToScoreTransformer : SymptomRarity.Transformer<Int> {
    ...
}

Generated module code - invalid class path

factory(qualifier=null) { <...>.transformers.SymptomRarityToScoreTransformer() } bind(<...>.models.Transformer::class)

Expected result

Line of code above should bind class with path <...>.models.SymptomRarity.Transformer::class

Lazy dependency in module

Using DSL I could create dependency in a module like this:
single { MyDependency(get(), inject()) }
Inject returns kotlin.Lazy so there was a possibility to avoid circular dependencies for example when I have a network interceptor which can perform a network request.

Using annotations, generated class uses only get() to obtain dependency. Is there any way to force change this to inject()?

Annotation class was declared in module.

Sorry for english. ๐Ÿ˜…

Describe the bug
When I created annotation and annotate as Single class, It was declared in defaultModule unintentionally.
Also, When I created class that want to declare module, and annotate my class, It won't be declared in defaultModule

To Reproduce

  1. created annotation class
@Single(createdAtStart = true)
annotation class RestApi
  1. annotate my class
@RestApi
class HelloController {
    ....
}
  1. build
  2. defaultModule result
val defaultModule = module {
    single(qualifier=null, createdAtStart=true) { some.package.RestApi() } // only annotation class was declared.
}

Expected behavior
What I Expected.

val defaultModule = module {
    single(qualifier=null, createdAtStart=true) { some.package.HelloController() }
}

Koin project used and used version (please complete the following information):
koin-core version 3.2.0-beta-1
koin-annotation 1.0.0-beta-1
ksp-version 1.6.10-1.0.2

Additional moduleDefinition
Nothing.

Generate empty module on multiplatform for common code

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.

Could not find io.insert-koin:koin-annotations:1.0.0-beta-1.

Hi, this looks promising, I'd love to define singletons and factories just by annotating the class, thus avoiding having to declare it in my module every time.

But when I try to run the sample app or add it to my project based on the guide provided I get the following error:

Could not resolve all files for configuration ':getting-started-koin-android:app:debugRuntimeClasspath'.
Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find io.insert-koin:koin-annotations:1.0.0-beta-1.

Do you know why this might be?
Thanks

Skip constructor params that have a default value

Is your feature request related to a problem? Please describe.
Some of my dependancies specify a default value for their constructor variables.

Describe the solution you'd like
Would it be possible to skip values that are already instantiated.

Describe alternatives you've considered
Today I have to add additional dependencies to the graph that I would otherwise not have added.

DefinitonParameterException - No value found for type when using annotations

Describe the bug
After migrating from 'regular' implementation to annotations, I get the following exception (snippet):

org.koin.core.error.DefinitionParameterException: No value found for type 'com.example.myapp.domain.repository.MyRepository'
        at org.koin.ksp.generated.KoinDomainModuleGenKt$KoinDomainModuleModule$1$10.invoke(KoinDomainModuleGen.kt:17)
        at org.koin.ksp.generated.KoinDomainModuleGenKt$KoinDomainModuleModule$1$10.invoke(KoinDomainModuleGen.kt:14)
        at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:54)

Following the call stack in the debugger, leads me to the instantiation of my ViewModel.
This project follows the principles of clean architecture and consists of multiple gradle modules (app, domain and data).

ViewModel (app module)

@KoinViewModel
class MyViewModel : ViewModel(), KoinComponent {

    private val myListUseCase: MyUseCase by inject()
    val myList: LiveData<List<Something>> by lazy {
        myListUseCase()
    }
}


Use case (domain module)

@Factory
class MyUseCase(
    @InjectedParam private val myRepository: MyRepository
) {
    operator fun invoke(): LiveData<List<Something>> =
        myRepository.loadList()
}

MyRepository (domain module)

interface MyRepository {
    fun loadList(): LiveData<List<Something>>
}

Implementation of MyRepository (data module)

@Single
internal class MyRepositoryImpl(
    @InjectedParam private val myDao: MyDao
) : BaseRepository(), DummyRepository {
    override fun loadList(): LiveData<List<Something>> {
        return myDao.loadList()
    }
}

Koin modules: (reside in their respective gradle modules, in the di subpackage)

@Module
@ComponentScan("com.example.myapp")
class KoinAppModule
@Module
@ComponentScan("com.example.myapp.domain")
class KoinDomainpModule
@Module
@ComponentScan("com.example.myapp.data")
class KoinDataModule
val customDataModule = module {
    single { Database.create() }
    single { get<Database>().myDao() }
}

Starting Koin:

startKoin {
    androidLogger()
    androidContext(this@MyApplicationClass)
    modules(
        KoinAppModule().module,
        KoinDomainModule().module,
        KoinDataModule().module,
        customDataModule
    )
}

Additional information:

  • When i place a breakpoint on the generated code for MyUseCase (in KoinDomainModuleGen.kt, I noticed that the params are empty, likely the cause of the exception. But I don't understand why the parameters are empty.
  • The project runs without issue when I use Koin the 'regular' way only (using version 3.1.6, have not tried 3.2.0-beta-2 there)

Expected behavior
All injected dependencies are resolved properly and no exception occurs

Koin project used and used version:
koin-core and koin-android version: 3.2.0-beta-1 (api in domain module, on which the other modules have a dependency)
koin-annotations version: 1.0.0-beta-2 (api in domain module, on which the other modules have a dependency)
ksp plugin version: 1.6.20-1.0.5 (in all modules)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.