kosi-libs / Kodein

Painless Kotlin Dependency Injection
https://kosi-libs.org/kodein
MIT License
3.22k stars 176 forks source link

iOS NotFoundException: No binding found #458

Open slartus opened 2 months ago

slartus commented 2 months ago

versions: kotlin 1.9.x-2.0.20 kodein: 7.21.2 - 7.22.0 target: iOS

reproduce steps:

interface Dice {
    fun getName(): String
}

class DiceImpl : Dice {
    override fun getName(): String = "DiceImpl"
}

val di = DI {
    bindSingleton { DiceImpl() }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    val text = remember { di.direct.instance<Dice>().getName() }
    Text(
        text = "Hello $text!",
        modifier = modifier
    )
}

crash:

Uncaught Kotlin exception: org.kodein.di.DI.NotFoundException: No binding found for Dice
    at 0   KotlinProject                       0x104cf19db        kfun:kotlin.Throwable#<init>(kotlin.String?){} + 119 
    at 1   KotlinProject                       0x104ceb4e7        kfun:kotlin.Exception#<init>(kotlin.String?){} + 115 
    at 2   KotlinProject                       0x104ceb707        kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 115 
    at 3   KotlinProject                       0x1052f04d3        kfun:org.kodein.di.DI.NotFoundException#<init>(org.kodein.di.DI.Key<*,*,*>;kotlin.String){} + 115 
    at 4   KotlinProject                       0x10530e4d7        kfun:org.kodein.di.internal.DIContainerImpl#factory(org.kodein.di.DI.Key<0:0,0:1,0:2>;0:0;kotlin.Int){0§<kotlin.Any>;1§<kotlin.Any?>;2§<kotlin.Any>}kotlin.Function1<0:1,0:2> + 4595 
    at 5   KotlinProject                       0x10531c9a7        kfun:org.kodein.di.DIContainer#factory(org.kodein.di.DI.Key<0:0,0:1,0:2>;0:0;kotlin.Int){0§<kotlin.Any>;1§<kotlin.Any?>;2§<kotlin.Any>}kotlin.Function1<0:1,0:2>-trampoline + 123 
    at 6   KotlinProject                       0x1052f43bb        kfun:org.kodein.di.DIContainer#factory$default(org.kodein.di.DI.Key<0:0,0:1,0:2>;0:0;kotlin.Int;kotlin.Int){0§<kotlin.Any>;1§<kotlin.Any?>;2§<kotlin.Any>}kotlin.Function1<0:1,0:2> + 203 
    at 7   KotlinProject                       0x1052f46c7        kfun:org.kodein.di.DIContainer#provider(org.kodein.di.DI.Key<0:0,kotlin.Unit,0:1>;0:0;kotlin.Int){0§<kotlin.Any>;1§<kotlin.Any>}kotlin.Function0<0:1> + 215 
    at 8   KotlinProject                       0x10531cc83        kfun:org.kodein.di.DIContainer#provider(org.kodein.di.DI.Key<0:0,kotlin.Unit,0:1>;0:0;kotlin.Int){0§<kotlin.Any>;1§<kotlin.Any>}kotlin.Function0<0:1>-trampoline + 123 
    at 9   KotlinProject                       0x1052f481f        kfun:org.kodein.di.DIContainer#provider$default(org.kodein.di.DI.Key<0:0,kotlin.Unit,0:1>;0:0;kotlin.Int;kotlin.Int){0§<kotlin.Any>;1§<kotlin.Any>}kotlin.Function0<0:1> + 203 
    at 10  KotlinProject                       0x105319c63        kfun:org.kodein.di.internal.DirectDIBaseImpl#Instance(org.kodein.type.TypeToken<0:0>;kotlin.Any?){0§<kotlin.Any>}0:0 + 559 
    at 11  KotlinProject                       0x10531e827        kfun:org.kodein.di.DirectDI#Instance(org.kodein.type.TypeToken<0:0>;kotlin.Any?){0§<kotlin.Any>}0:0-trampoline + 115 
    at 12  KotlinProject  
DmitriyZaitsev commented 2 weeks ago

@slartus, it looks like the issue is due to a missing binding for the interface type. In Kodein, you need to explicitly bind the interface to its implementation to allow the framework to resolve Dice as expected.

Updating your setup like this should solve the problem:

val di = DI {
    bindSingleton<Dice> { DiceImpl() }
}

This binds the Dice interface to the DiceImpl implementation, allowing di.direct.instance() to resolve correctly.

Hope this helps!

slartus commented 2 weeks ago

It is confusing that registration of impl works for android without specifying an interface