Koin: Named BeanDefinition not using 'primary_type'

Created on 28 Aug 2019  路  5Comments  路  Source: InsertKoinIO/koin

Describe the bug
When defining two objects with same named string, it fails with DefinitionOverrideException

To Reproduce
Steps to reproduce the behavior:

  1. Create definitions like:
factory(named("statusOne")){ StatusObject(get(named("statusOne"))) }
single(named("statusOne")){ StatusObjectConstructorParam() }
  1. start app... startKoin{...}

Expected behavior
named definitions also check primary_type to determine object definition

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

    implementation "org.koin:koin-androidx-scope:2.0.1"
    implementation "org.koin:koin-androidx-viewmodel:2.0.1"
    implementation "org.koin:koin-androidx-ext:2.0.1"

this appeard after migrating from 1.0.2 to 2.0.1 - on 1.x it such definitions were working fine, on 2.x every named (eg. based on enums) definitions should be changed, which is painful job ;)
or there is some other way I didn't in docs?

question

All 5 comments

Hello @bovquier,

this behavior is intended: a qualifier is unique for all definitions. What is your use case behind reusing the same qualifier?

Hello @bovquier
I can give you an example.
Let's assume we have a base fragment class with different classes expected to be injected. And they are injected based on some string key passed via constructor by child fragment class.

class BaseFragment(nameKey: String) {
       private val listAdapter: BaseAdapter by inject(named(nameKey))
       private val viewModel: BaseViewModel by viewModel(named(nameKey))

      ....
}

class ChildFragment1 : BaseFragment("key1") {...}

class ChildFragment2 : BaseFragment("key2") {...}

While this might read intuitive, I tend to agree, there is no reason why you can't use distinct qualifiers. There is no logical reason why the same qualifier should be used.

Logic is to avoid having next

factory(named("one_vm")){ ... }
factory(named("one_adapter")){ ... }
factory(named("one_controller")){ ... }
factory(named("one_something")){ ... }

factory(named("two_vm")){ ... }
factory(named("two_adapter")){ ... }
factory(named("two_controller")){ ... }
factory(named("two_something")){ ... }

This way people will end writing their tool functions like namedVm, namedController.

Could you suggest something more "koin native" instead?

@arnaudgiuliani the reason is eg. I'm using ItemKeyedDataSource and DataSource.Factory from jetpack paging, and same implementations for few source types (eg. based on item status), this doesn't allow me to make them defined in simple way like in Kotlin1 (have such setup for that). In Koin2, this will need to create ActiveDataSource/PendingDataSource/LockedDataSource, to match the requirements.
In Koin1 I have something like:

        MyProjectsAdapter.ProjectsPagesItems.values().forEach { page -> single(page.name) { ProjectsDataSourceFactory() } }
        MyProjectsAdapter.ProjectsPagesItems.values().forEach { page -> factory(page.name) { ProjectsDataSourceManager(get(page.name)) } }

and I have 2 lines, and do not think about how many PagesTypes there will be, all adapter pages will have its sources injected. But couldn't achive that in K2, but I may be missing something in docs, and you, guys, can give some hint, if there is such simple approach for that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haroldadmin picture haroldadmin  路  3Comments

sankarsana picture sankarsana  路  4Comments

AHarazim picture AHarazim  路  3Comments

miladsalimiiii picture miladsalimiiii  路  3Comments

leodeleon22 picture leodeleon22  路  4Comments