InsertKoinIO / koin

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

koin can't di different Object of the same class ? #675

Closed DaveBoy closed 4 years ago

DaveBoy commented 4 years ago

i want to di double object like this:

val objectModel= module{
    single { ObjectBoxUtil.boxStore.boxFor<Song>() }
    single{ ObjectBoxUtil.boxStore.boxFor<Album>() }
}

when i add one of them,it's ok but when i add the second one:

     Caused by: org.koin.core.error.DefinitionOverrideException: Already existing definition or try to override an existing one: [type:Single,primary_type:'io.objectbox.Box']
        at org.koin.core.registry.BeanRegistry.addDefinition(BeanRegistry.kt:144)
        at org.koin.core.registry.BeanRegistry.saveDefinition(BeanRegistry.kt:101)
        at org.koin.core.registry.BeanRegistry.saveDefinitions(BeanRegistry.kt:71)
        at org.koin.core.registry.BeanRegistry.loadModules(BeanRegistry.kt:49)
        at org.koin.core.KoinApplication.loadModulesAndScopes(KoinApplication.kt:66)
        at org.koin.core.KoinApplication.access$loadModulesAndScopes(KoinApplication.kt:31)
        at org.koin.core.KoinApplication$modules$duration$1.invoke(KoinApplication.kt:54)
        at org.koin.core.KoinApplication$modules$duration$1.invoke(KoinApplication.kt:31)
        at org.koin.core.time.MeasureKt.measureDurationOnly(Measure.kt:28)
        at org.koin.core.KoinApplication.modules(KoinApplication.kt:53)
        at org.koin.core.KoinApplication.modules(KoinApplication.kt:44)
        at com.example.myapplication.App$onCreate$1.invoke(App.kt:26)
        at com.example.myapplication.App$onCreate$1.invoke(App.kt:12)
        at org.koin.core.context.GlobalContextKt.startKoin(GlobalContext.kt:72)
        at com.example.myapplication.App.onCreate(App.kt:17)
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1028)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5658)

i change it to this:

val objectModel= module{
    single (named("song")){ ObjectBoxUtil.boxStore.boxFor<Song>() }
    single (named("album")){ ObjectBoxUtil.boxStore.boxFor<Album>() }
}

it become this error:

 Caused by: org.koin.core.error.NoBeanDefFoundException: No definition found for 'io.objectbox.Box' has been found. Check your module definitions.
        at org.koin.core.scope.Scope.findDefinition(Scope.kt:170)
        at org.koin.core.scope.Scope.resolveInstance(Scope.kt:164)
        at org.koin.core.scope.Scope.get(Scope.kt:128)
        at com.example.myapplication.MainActivity$$special$$inlined$inject$1.invoke(ComponentCallbackExt.kt:51)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at com.example.myapplication.MainActivity.getSongBox(MainActivity.kt)
        at com.example.myapplication.MainActivity.initObjectBox(MainActivity.kt:31)
        at com.example.myapplication.MainActivity.onCreate(MainActivity.kt:18)
        at android.app.Activity.performCreate(Activity.java:6910)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2746)

the other code

//init
        startKoin {
            // use AndroidLogger as Koin Logger - default Level.INFO
            androidLogger()

            // use the Android context given there
            androidContext(this@App)

            // module list
            modules(objectModel)
        }

//use
    val songBox:Box<Song> by inject()

what's the correct action? please help me.thanks

DaveBoy commented 4 years ago

boxFor return the Box\<T> Koin Version is :2.0.1 // Koin AndroidX Scope features implementation "org.koin:koin-androidx-scope:$koin_version" // Koin AndroidX ViewModel features implementation "org.koin:koin-androidx-viewmodel:$koin_version" // Koin AndroidX Fragment features //implementation "org.koin:koin-androidx-fragment:$koin_version" // Koin AndroidX Experimental features implementation "org.koin:koin-androidx-ext:$koin_version"

kirich1409 commented 4 years ago

The problem is that Koin works in runtime and has no information about generics. You can find in the documentation

DaveBoy commented 4 years ago

The problem is that Koin works in runtime and has no information about generics. You can find in the documentation

i am not found this doc before,but this solution of the doc is same as my second try(add named),and it happen the error:

Caused by: org.koin.core.error.NoBeanDefFoundException: No definition found for 'io.objectbox.Box' has been found. Check your module definitions.
        at org.koin.core.scope.Scope.findDefinition(Scope.kt:170)
        at org.koin.core.scope.Scope.resolveInstance(Scope.kt:164)
        at org.koin.core.scope.Scope.get(Scope.kt:128)
        at com.example.myapplication.MainActivity$$special$$inlined$inject$1.invoke(ComponentCallbackExt.kt:51)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at com.example.myapplication.MainActivity.getSongBox(MainActivity.kt)
        at com.example.myapplication.MainActivity.initObjectBox(MainActivity.kt:31)
        at com.example.myapplication.MainActivity.onCreate(MainActivity.kt:18)
        at android.app.Activity.performCreate(Activity.java:6910)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2746)
DaveBoy commented 4 years ago

The problem is that Koin works in runtime and has no information about generics. You can find in the documentation

i use it like this in MainActivity

//use
    val songBox:Box<Song> by inject()
kirich1409 commented 4 years ago

You need to use the same qualifier in declaration and injection:

val objectModel= module {
    single (named("song")){ ObjectBoxUtil.boxStore.boxFor<Song>() }
    single (named("album")){ ObjectBoxUtil.boxStore.boxFor<Album>() }
}
val songBox:Box<Song>  by inject(qualifier = named("song"))
val songBox:Box<Album> by inject(qualifier = named("album"))
DaveBoy commented 4 years ago

tks very much ,i found it right now,i read the doc before,not this, and i found the solution after read the new doc which you give me