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

Using constructor DSL to bind multiple classes via lambdas to the same interface does not work #1463

Closed
sschuberth opened this issue Oct 30, 2022 · 4 comments
Assignees
Milestone

Comments

@sschuberth
Copy link
Contributor

Describe the bug

The code

module {
    singleOf(::CsvExporter) { bind<Exporter>() }
    singleOf(::ExcelExporter) { bind<Exporter>() }
}

throws org.koin.core.error.DefinitionOverrideException: Already existing definition for [Singleton:'dev.schuberth.stan.exporters.ExcelExporter',binds:dev.schuberth.stan.exporters.Exporter] at dev.schuberth.stan.exporters.Exporter::_root_.

Note that using the alternative operator-syntax

module {
    singleOf(::CsvExporter) bind Exporter::class
    singleOf(::ExcelExporter) bind Exporter::class
}

works.

To Reproduce

Just use above code snippets.

Expected behavior

{ bind<Exporter>() } syntax should work just like bind Exporter::class syntax.

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

koin-core version 3.2.2

Additional moduleDefinition

n/a

@1gravity
Copy link

1gravity commented Oct 30, 2022

IMO

module {
    singleOf(::CsvExporter) bind Exporter::class
    singleOf(::ExcelExporter) bind Exporter::class
}

should also throw a DefinitionOverrideException because you're binding two implementations to the same interface and Koin doesn't know which one to inject. It seems to pick the second one but

  1. that's not a documented behavior and
  2. it makes the first bind obsolete so why add it in the first place (ok I know what you're trying to do but outside of your use case, having these two binds in one module doesn't make sense)?

@sschuberth
Copy link
Contributor Author

ok I know what you're trying to do but outside of your use case, having these two binds in one module doesn't make sense

Yes, as you know from my SO question I'm looking at Koin from a Service Locator / plugin registry perspective. And there, it makes sense to be able to bind multiple implementations to the same interface, so all plugin instances could be retrieved via app.koin.getAll<Exporter>(). If that shouldn't be allowed, what's the purpose of the getAll() API call after all?

@1gravity
Copy link

ok I know what you're trying to do but outside of your use case, having these two binds in one module doesn't make sense

Yes, as you know from my SO question I'm looking at Koin from a Service Locator / plugin registry perspective. And there, it makes sense to be able to bind multiple implementations to the same interface, so all plugin instances could be retrieved via app.koin.getAll<Exporter>(). If that shouldn't be allowed, what's the purpose of the getAll() API call after all?

Yes you're right, I didn't understand that Koin indeed allows to inject multiple implementations that can be retrieved into a list .

@arnaudgiuliani arnaudgiuliani added status:checking currently in analysis - discussion or need more detailed specs and removed status:accepted accepted to be developed labels Nov 2, 2022
@sschuberth sschuberth changed the title Using constructor DSL to bind mutiple classes via lambdas to the same interface does not work Using constructor DSL to bind multiple classes via lambdas to the same interface does not work Nov 7, 2022
@arnaudgiuliani arnaudgiuliani added status:accepted accepted to be developed and removed status:checking currently in analysis - discussion or need more detailed specs labels Dec 13, 2022
@arnaudgiuliani
Copy link
Member

I fixed it back, to allow bind() for 2 same type

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

3 participants