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

shouldn't inject parameters when qualifier is present #2090

Open
wants to merge 1 commit into
base: 4.1.0
Choose a base branch
from

Conversation

luozejiaqun
Copy link

example:

module {
    single(named("echo")) { "Hello," + it.get<String>() }
}

koin.get<String>(named("echo")) { parametersOf("World!") } // this should be "Hello,World!", but we get "World!"

PS. this issue will effect multibinding with parameters:

module {
    declareSetMultibinding<String> {
        intoSet { it.get<String>() + "1" }
        intoSet { it.get<String>() + "2" }
    }
}
koin.getSetMultibinding<String> { parametersOf("set element prefix") }

multibinding #1951

@luozejiaqun
Copy link
Author

luozejiaqun commented Dec 25, 2024

i also think it's kind of weird that we can't do this:

module {
    single { "Hello," + it.get<String>() }
}

koin.get<String> { parametersOf("World!") } // never get "Hello,World!", always "World!"

when the declared type is same to the parameter and no qualifier presents, the parameter always win.

@arnaudgiuliani
Copy link
Member

I don't understand your point here 🤔 Let avoid mixing topic 👍

@arnaudgiuliani arnaudgiuliani added the status:checking currently in analysis - discussion or need more detailed specs label Jan 9, 2025
@luozejiaqun
Copy link
Author

The key point is the inject order:

// code from Scope
private fun <T> resolveFromContext(
  instanceContext: ResolutionContext
): T {
  return resolveFromInjectedParameters(instanceContext)
      ?: resolveFromRegistry(instanceContext)
      ?: resolveFromStackedParameters(instanceContext)
      ?: resolveFromScopeSource(instanceContext)
      ?: resolveFromParentScopes(instanceContext)
      ?: throwNoDefinitionFound(instanceContext)
}

If we want to resolve an instance of class T, and we provide an parameter which is also class T, then we will always get the parameter:

module {
    single<String> { parameters -> "Hello," + parameters.get<String>() }
}

koin.get<String> { parametersOf("World!") } == "World!"

This it the current implement, becase we can't tell which instance is wanted.
But, if we resolve an instance with qualifier, there is no way the parameter wins, since parameter has nothing to do with qualifier.

module {
    single<String>(named("echo")) { parameters -> "Hello," + parameters.get<String>() }
}

koin.get<String>(named("echo")) { parametersOf("World!") } // expected "Hello,World!", but currently we get "World!"

All in all, I just find a situation where we should skip the parameter injection and continue the rest.

@arnaudgiuliani
Copy link
Member

it's about how you shadow your definition instances. The latest additions in your context show be found first. If you try to pass an instance T in the parameters, you will solve this param first as it's the most recent additions.

If you use qualifier, it won't find it in the parameters as it doesn't have been tagged with qualifier.

@luozejiaqun
Copy link
Author

@arnaudgiuliani exactly, but the parameter injection doesn't check the qualifier, only the type:

    private inline fun <T> resolveFromInjectedParameters(ctx: ResolutionContext): T? {
        return if (ctx.parameters == null) null
            else {
            _koin.logger.debug("|- ? ${ctx.debugTag} look in injected parameters")
            ctx.parameters.getOrNull(clazz = ctx.clazz)
        }
    }

@arnaudgiuliani
Copy link
Member

I see your point, we could skip parameter stage if we have qualifier 👍

@arnaudgiuliani arnaudgiuliani added the type:improvement Improving a current feature label Jan 17, 2025
@arnaudgiuliani arnaudgiuliani added this to the 4.1.0 milestone Jan 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:checking currently in analysis - discussion or need more detailed specs type:improvement Improving a current feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants