InsertKoinIO / koin

Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
https://insert-koin.io
Apache License 2.0
9.09k stars 719 forks source link

Cause NoBeanDefFoundException when you create a new koinApplication and link to its root scope #1889

Open EvgenyMeltsaykin opened 5 months ago

EvgenyMeltsaykin commented 5 months ago

Describe the bug Cause NoBeanDefFoundException when you create a new koinApplication and link to its root scope

To Reproduce this test case causes an error I've run it with koin 3.5.6

    @OptIn(KoinInternalApi::class)
    @Test
    fun scope_component1() {
        class One
        class Two(private val one: One)

        class ComponentKoinContext {
            @OptIn(KoinInternalApi::class)
            fun getKoinScope(modules: List<Module>): Scope {
                val koinApp = koinApplication { modules(modules) }
                return koinApp.koin.scopeRegistry.rootScope
            }
        }

        class ScopeComponent(parentScope: Scope, modules: List<Module>) : KoinScopeComponent {
            override val scope: Scope = createScope()

            init {
                scope.linkTo(parentScope)
                scope.getKoin().loadModules(modules)
            }
        }

        startKoin {
            printLogger(Level.DEBUG)
            modules()
        }

        val componentRootScope = ComponentKoinContext().getKoinScope(
            listOf(
                module {
                    singleOf(::One)
                }
            )
        )

        val childComponent = ScopeComponent(parentScope = componentRootScope, modules = listOf(
            module {
                single { Two(get()) }
            }
        ))

        childComponent.scope.get<Two>()
    }

If I run this test, I got exception like below.

org.koin.core.error.InstanceCreationException: Could not create instance for '[Singleton:'org.koin.core.ScopeTest$scope_component1$Two']'
    at app//org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:57)
    at app//org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
    at app//org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:55)
    at app//org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:53)
    at app//org.koin.mp.KoinPlatformTools.synchronized(KoinPlatformTools.kt:36)
    at app//org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:53)
    at app//org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:109)
    at app//org.koin.core.scope.Scope.resolveValue(Scope.kt:247)
    at app//org.koin.core.scope.Scope.resolveInstance(Scope.kt:233)
    at app//org.koin.core.scope.Scope.get(Scope.kt:205)
    at app//org.koin.core.scope.Scope.getOrNull(Scope.kt:176)
    at app//org.koin.core.scope.Scope.findInOtherScope(Scope.kt:286)
    at app//org.koin.core.scope.Scope.resolveValue(Scope.kt:264)
    at app//org.koin.core.scope.Scope.resolveInstance(Scope.kt:233)
    at app//org.koin.core.scope.Scope.get(Scope.kt:205)
    at app//org.koin.core.ScopeTest.scope_component1(ScopeTest.kt:362)
    at java.base@17.0.9/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base@17.0.9/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base@17.0.9/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base@17.0.9/java.lang.reflect.Method.invoke(Unknown Source)
    at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at app//org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at app//org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at app//org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at app//org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at app//org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at app//org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at app//org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at app//org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at app//org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:108)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:57)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:39)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
    at java.base@17.0.9/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base@17.0.9/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base@17.0.9/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base@17.0.9/java.lang.reflect.Method.invoke(Unknown Source)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.koin.core.error.NoBeanDefFoundException: No definition found for type 'org.koin.core.ScopeTest$scope_component1$One'. Check your Modules configuration and add missing type and/or qualifier!
    at app//org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:301)
    at app//org.koin.core.scope.Scope.resolveValue(Scope.kt:271)
    at app//org.koin.core.scope.Scope.resolveInstance(Scope.kt:233)
    at app//org.koin.core.scope.Scope.get(Scope.kt:205)
    at app//org.koin.core.ScopeTest$scope_component1$scopeComponent$1$1.invoke(ScopeTest.kt:264)
    at app//org.koin.core.ScopeTest$scope_component1$scopeComponent$1$1.invoke(ScopeTest.kt:252)
    at app//org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
    ... 58 more

Expected behavior Test should run successfully.

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

VasilyRylov commented 3 months ago

Hello! In the line "val koinApp = koinApplication { modules(modules) }" a local koinApplication was created and in the line "startKoin {" - a global one

in the line "scope.linkTo(parentScope)" - an attempt to link two scopes from different koinApplications, which is why it is not possible to find the bean definition