diff --git a/examples/android-coffee-maker/src/main/java/org/koin/sample/androidx/di/AppModules.kt b/examples/android-coffee-maker/src/main/java/org/koin/sample/androidx/di/AppModules.kt index d2623d0a..3aba3eba 100644 --- a/examples/android-coffee-maker/src/main/java/org/koin/sample/androidx/di/AppModules.kt +++ b/examples/android-coffee-maker/src/main/java/org/koin/sample/androidx/di/AppModules.kt @@ -6,10 +6,15 @@ import org.koin.sample.android.library.CommonModule import org.koin.sample.androidx.repository.RepositoryModule import org.koin.sample.clients.ClientModule -@Module(includes = [DataModule::class]) -@ComponentScan("org.koin.sample.androidx.app") -class AppModule +//@Module(includes = [DataModule::class]) +//@ComponentScan("org.koin.sample.androidx.app") +//class AppModule +// +//@Module(includes = [CommonModule::class, RepositoryModule::class]) +//@ComponentScan("org.koin.sample.androidx.data") +//internal class DataModule + @Module(includes = [CommonModule::class, ClientModule::class, RepositoryModule::class]) -@ComponentScan("org.koin.sample.androidx.data") -internal class DataModule \ No newline at end of file +@ComponentScan("org.koin.sample.androidx.data", "org.koin.sample.androidx.app") +class AppModule diff --git a/examples/android-coffee-maker/src/test/java/AndroidModuleTest.kt b/examples/android-coffee-maker/src/test/java/AndroidModuleTest.kt index c3fc34d2..6419a615 100644 --- a/examples/android-coffee-maker/src/test/java/AndroidModuleTest.kt +++ b/examples/android-coffee-maker/src/test/java/AndroidModuleTest.kt @@ -15,7 +15,7 @@ import org.koin.sample.androidx.app.ScopedStuff import org.koin.sample.androidx.data.DataConsumer import org.koin.sample.androidx.data.MyDataConsumer import org.koin.sample.androidx.di.AppModule -import org.koin.sample.androidx.di.DataModule +//import org.koin.sample.androidx.di.DataModule import org.koin.sample.androidx.repository.RepositoryModule class AndroidModuleTest { @@ -25,7 +25,7 @@ class AndroidModuleTest { val koin = startKoin { modules( // defaultModule, - DataModule().module, + //DataModule().module, RepositoryModule().module, AppModule().module, ) @@ -48,4 +48,30 @@ class AndroidModuleTest { stopKoin() } + + @Test + fun run_all_modules_common() { + val koin = startKoin { + modules( +// defaultModule, + AppModule().module, + ) + }.koin + + val commonRepository = koin.get() + assert(!commonRepository.lazyParam.isInitialized()) + assert(commonRepository.lazyParam != null) + + val scope = koin.createScope() + scope.get() + + assert(koin.getOrNull() != null) + assert(koin.getOrNull() != null) + + assert(koin.getOrNull() != null) + + + stopKoin() + } + } \ No newline at end of file diff --git a/examples/coffee-maker/src/main/kotlin/org/koin/example/di/CoffeeAppModule.kt b/examples/coffee-maker/src/main/kotlin/org/koin/example/di/CoffeeAppModule.kt index 084346e7..d102b680 100644 --- a/examples/coffee-maker/src/main/kotlin/org/koin/example/di/CoffeeAppModule.kt +++ b/examples/coffee-maker/src/main/kotlin/org/koin/example/di/CoffeeAppModule.kt @@ -18,7 +18,7 @@ class CoffeeAppModule { } @Module -@ComponentScan("org.koin.example.test") +@ComponentScan(value = ["org.koin.example.test"]) class CoffeeTesterModule { @Single diff --git a/projects/koin-annotations/src/commonMain/kotlin/org/koin/core/annotation/CoreAnnotations.kt b/projects/koin-annotations/src/commonMain/kotlin/org/koin/core/annotation/CoreAnnotations.kt index 15927446..f0679f49 100644 --- a/projects/koin-annotations/src/commonMain/kotlin/org/koin/core/annotation/CoreAnnotations.kt +++ b/projects/koin-annotations/src/commonMain/kotlin/org/koin/core/annotation/CoreAnnotations.kt @@ -202,13 +202,14 @@ annotation class PropertyValue(val value: String) annotation class Module(val includes: Array> = [], val createdAtStart: Boolean = false) /** - * Gather definitions declared with Koin definition annotation - * Will scan in current package or with the explicit package name + * Gather definitions declared with Koin definition annotation. + * Will scan in current package or with the explicit packages names. + * For scan current package use empty value array or empty string. * - * @param value: package to scan + * @param value: packages to scan */ @Target(AnnotationTarget.CLASS, AnnotationTarget.FIELD) -annotation class ComponentScan(val value: String = "") +annotation class ComponentScan(vararg val value: String = []) /** * Tag a dependency as already provided by Koin (like DSL declaration, or internals) diff --git a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/AnnotationMetadata.kt b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/AnnotationMetadata.kt index 655082e2..29640b08 100644 --- a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/AnnotationMetadata.kt +++ b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/AnnotationMetadata.kt @@ -81,6 +81,14 @@ fun includedModules(annotation: KSAnnotation): List? { return declaredBindingsTypes?.map { it.declaration } } +fun componentsScanValue(annotation: KSAnnotation): List? { + val declaredBindingsTypes = annotation.arguments.firstOrNull { arg -> arg.name?.asString() == "value" }?.value as? List? + + val values = if (declaredBindingsTypes?.isEmpty() == true) listOf("") else declaredBindingsTypes + + return values?.map { KoinMetaData.Module.ComponentScan(it.trim()) } +} + fun isCreatedAtStart(annotation: KSAnnotation): Boolean? { return annotation.arguments.firstOrNull { it.name?.asString() == "createdAtStart" }?.value as? Boolean } diff --git a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt index 1f6764c4..583c9602 100644 --- a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt +++ b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/metadata/KoinMetaData.kt @@ -31,7 +31,7 @@ sealed class KoinMetaData { val definitions: MutableList = mutableListOf(), val externalDefinitions: MutableList = mutableListOf(), val type: ModuleType = ModuleType.FIELD, - val componentScan: ComponentScan? = null, + val componentsScan: Set = emptySet(), val includes: List? = null, val isCreatedAtStart: Boolean? = null, val visibility: Visibility = Visibility.PUBLIC, @@ -52,15 +52,16 @@ sealed class KoinMetaData { data class ComponentScan(val packageName: String = "") fun acceptDefinition(defPackageName: String): Boolean { - return when { - componentScan == null -> false - componentScan.packageName.isNotEmpty() -> defPackageName.contains( - componentScan.packageName, - ignoreCase = true - ) - - componentScan.packageName.isEmpty() -> defPackageName.contains(packageName, ignoreCase = true) - else -> false + return componentsScan.any { componentScan -> + when { + componentScan.packageName.isNotEmpty() -> defPackageName.contains( + componentScan.packageName, + ignoreCase = true + ) + + componentScan.packageName.isEmpty() -> defPackageName.contains(packageName, ignoreCase = true) + else -> false + } } } diff --git a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KoinMetaDataScanner.kt b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KoinMetaDataScanner.kt index 09aa9dcf..22f0d3d5 100644 --- a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KoinMetaDataScanner.kt +++ b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/KoinMetaDataScanner.kt @@ -124,7 +124,7 @@ class KoinMetaDataScanner( val moduleList = hashMapOf() val emptyScanList = arrayListOf() forEach { module -> - module.componentScan?.let { scan -> + module.componentsScan.forEach { scan -> when (scan.packageName) { "" -> emptyScanList.add(module) else -> if (moduleList.contains(scan.packageName)) { diff --git a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/ModuleScanner.kt b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/ModuleScanner.kt index 62041cc4..7dca285b 100644 --- a/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/ModuleScanner.kt +++ b/projects/koin-ksp-compiler/src/jvmMain/kotlin/org/koin/compiler/scanner/ModuleScanner.kt @@ -31,7 +31,7 @@ class ModuleScanner( val annotations = declaration.annotations val includes = getIncludedModules(annotations) val isCreatedAtStart = getIsCreatedAtStart(annotations) - val componentScan = getComponentScan(annotations) + val componentsScan = getComponentsScan(annotations) val isExpect = declaration.isExpect val isActual = declaration.isActual @@ -46,7 +46,7 @@ class ModuleScanner( packageName = modulePackage, name = name, type = type, - componentScan = componentScan, + componentsScan = componentsScan, includes = includes.toModuleIncludes(), isCreatedAtStart = isCreatedAtStart, visibility = declaration.getVisibility(), @@ -76,12 +76,9 @@ class ModuleScanner( return module?.let { isCreatedAtStart(it) } } - private fun getComponentScan(annotations: Sequence): KoinMetaData.Module.ComponentScan? { + private fun getComponentsScan(annotations: Sequence): Set { val componentScan = annotations.firstOrNull { it.shortName.asString() == "ComponentScan" } - return componentScan?.let { a -> - val value : String = a.arguments.firstOrNull { arg -> arg.name?.asString() == "value" }?.value as? String? ?: "" - KoinMetaData.Module.ComponentScan(value) - } + return componentScan?.let(::componentsScanValue)?.toSet() ?: emptySet() } private fun addFunctionDefinition(element: KSAnnotated): KoinMetaData.Definition? {