Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Koin 4.0.0: Can't get injected parameter #0 from DefinitionParameters[] #2015

Open
ianbrandt opened this issue Oct 4, 2024 · 0 comments
Open

Comments

@ianbrandt
Copy link

ianbrandt commented Oct 4, 2024

Describe the bug
This may be a hacky thing to do, but with Koin 3 I had an example of declaring a singleton for an externally created instance by way of injected parameters:

// A parameterized component where the parameter ends up being the component itself
single(named(REVERSE_INJECTED_COMPONENT)) { (externalComponent: ExternalComponent) ->
	externalComponent
}

Example of supplying the external singleton as a parameter:

// "Reverse inject" the external component into the Koin module as an
// injection parameter for a singleton that is the parameter itself
get<ExternalComponent>(named(REVERSE_INJECTED_COMPONENT)) {
	parametersOf(ExternalComponent(TESTING))
}

When I upgrade from 3.5.6 to 4.0.0 (with no other changes), this no longer works:

Could not create instance for '[Singleton: 'org.sdkotlin.koin.hello.ExternalComponentContainer',qualifier:reverse injected component container]'
org.koin.core.error.InstanceCreationException: Could not create instance for '[Singleton: 'org.sdkotlin.koin.hello.ExternalComponentContainer',qualifier:reverse injected component container]'
	at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:58)
	at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
	at org.koin.core.instance.SingleInstanceFactory.get$lambda$0(SingleInstanceFactory.kt:55)
	at org.koin.mp.KoinPlatformTools.synchronized(KoinPlatformTools.kt:36)
	at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:53)
	at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:110)
	at org.koin.core.scope.Scope.resolveFromRegistry(Scope.kt:321)
	at org.koin.core.scope.Scope.resolveFromContext(Scope.kt:311)
	at org.koin.core.scope.Scope.stackParametersCall(Scope.kt:273)
	at org.koin.core.scope.Scope.resolveInstance(Scope.kt:259)
	at org.koin.core.scope.Scope.resolveWithOptionalLogging(Scope.kt:232)
	at org.koin.core.scope.Scope.get(Scope.kt:215)
	at org.sdkotlin.koin.it.hello.HelloModuleIT.test reverse injecting an external component(HelloModuleIT.kt:149)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for '[Singleton: 'org.sdkotlin.koin.hello.ExternalComponent',qualifier:reverse injected component]'
	at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:58)
	at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
	at org.koin.core.instance.SingleInstanceFactory.get$lambda$0(SingleInstanceFactory.kt:55)
	at org.koin.mp.KoinPlatformTools.synchronized(KoinPlatformTools.kt:36)
	at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:53)
	at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:110)
	at org.koin.core.scope.Scope.resolveFromRegistry(Scope.kt:321)
	at org.koin.core.scope.Scope.resolveFromContext(Scope.kt:311)
	at org.koin.core.scope.Scope.stackParametersCall(Scope.kt:273)
	at org.koin.core.scope.Scope.resolveInstance(Scope.kt:259)
	at org.koin.core.scope.Scope.resolveWithOptionalLogging(Scope.kt:232)
	at org.koin.core.scope.Scope.get(Scope.kt:215)
	at org.sdkotlin.koin.hello.HelloModuleKt.helloModule$lambda$5$lambda$4(helloModule.kt:52)
	at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:51)
	... 15 more
Caused by: org.koin.core.error.NoParameterFoundException: Can't get injected parameter #0 from DefinitionParameters[] for type 'org.sdkotlin.koin.hello.ExternalComponent'
	at org.koin.core.parameter.ParametersHolder.elementAt(ParametersHolder.kt:45)
	at org.sdkotlin.koin.hello.HelloModuleKt$helloModule$1$5.invoke-Syj1E0w(helloModule.kt:38)
	at org.sdkotlin.koin.hello.HelloModuleKt$helloModule$1$5.invoke(helloModule.kt:26)
	at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:51)
	... 28 more

To Reproduce

Reproducer project:

https://github.com/sdkotlin/sd-kotlin-talks/tree/4b4df2e61eaac75141e74fc1eaf3ec2e37954425

The module with parameterized singleton definition:

https://github.com/sdkotlin/sd-kotlin-talks/blob/4b4df2e61eaac75141e74fc1eaf3ec2e37954425/subprojects/di-with-koin/src/main/kotlin/org/sdkotlin/koin/hello/helloModule.kt#L26

Test that passes with 3.5.6, but fails with 4.0.0:

https://github.com/sdkotlin/sd-kotlin-talks/blob/4b4df2e61eaac75141e74fc1eaf3ec2e37954425/subprojects/di-with-koin/src/it/kotlin/org/sdkotlin/koin/it/hello/HelloModuleIT.kt#L63

Expected behavior
I developed this example a while back as a possible alternative to getKoin().declare(...). I don't know of any advantage the injected parameter approach has over .declare(...), so if you want to close this issue as "Won't Fix" that's probably fine. I'm really just reporting this in case it's indicative of a more general bug that might have been introduced in 4.0.0. Otherwise, it may be good to add some documentation or better error messaging regarding injected parameters not being able to directly become components themselves.

Koin module and version:
koin-core:4.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants