Search code examples
androidkotlinkodein

Passing lambda as argument in Kodein


I am using Kodein for dependency injection on Android (in Kotlin, of course), but I am struggling with one aspect: I can't seem to pass a lambda as an argument to a factory. It compiles correctly but fails at runtime (something I though Kodein as meant to protect against).

In my Application class, I do the following binding:

class MyApplication : Application(), KodeinAware {
    override val kodein by Kodein.lazy {
        ...
        bind<SimpleButtonListener>() with factory { func: () -> Unit -> SimpleButtonListener(func) }
    }
}

In my activity, I invoke it like this:

val onClick = { startActivity(EmailIntent()) }
val clickListener : SimpleButtonListener by with(onClick).instance()

I also tried this unsuccessfully:

val clickListener : SimpleButtonListener by with({ startActivity(EmailIntent()) }).instance()

But I always get the same issue when I run:

com.github.salomonbrys.kodein.Kodein$NotFoundException: No factory found for bind() with ? { ? }
... bind() with factory { Function0 -> SimpleButtonListener }

I'm still pretty new to Kotlin, so I'm not sure exactly where I have gone wrong. Is there a quirk or idiom in the language I have missed or is there a limitation of Kodein around lambdas as arguments?


Solution

  • This is a bug in Kodein 4 that is corrected in the next version of Kodein (version 5.0).

    In the mean time, here is the fix :

    val clickListener : SimpleButtonListener by With(generic(), onClick).instance()
    

    Sorry for the inconvenicence.