edvin / tornadofx

Lightweight JavaFX Framework for Kotlin
Apache License 2.0
3.67k stars 269 forks source link

Integration with Kodein #419

Closed elexx closed 7 years ago

elexx commented 7 years ago

This is not really an issue with TornadoFX, but more a question.

Until now I was using Guice as DI for my Kotlin/TornadoFX application. But Guice has its drawbacks when used in a Kotlin application, so I kept searching and found Kodein. When replacing Guice with Kodein, I however had some difficulties implementing DIContainer. The Wiki/Guide is only about Spring and Guice, can you help me with a sample on how to integrate Kodein?

edvin commented 7 years ago

Hi! I've never used Kodein myself, but judging from the example in the README, it should be as simple as extracting the instance using kodein.instance(), shouldn't it?

Can you show me your attempt, and what's missing?

elexx commented 7 years ago

I had

init {
    val kodeinInjector = KodeinInjector()
    FX.dicontainer = object : DIContainer {
        override fun <T : Any> getInstance(type: KClass<T>) = kodeinInjector.instance()
    }
}

which gave me a "Type inference failed: Not enough information to infer parameter T in inline fun KodeinInjectedBase.instance(tag: Any? = ...): InjectedProperty" on instance()

edvin commented 7 years ago

Ah, since you're not passing on the type but rather the type parameter, you need to utilize an inline function, which allows you to use reified generics. You could save your KodeinInjector to a companion object or just a package level value, and then create your own injection delegate:

inline fun <reified T : Any> kdi(): ReadOnlyProperty<Component, T> = object : ReadOnlyProperty<Component, T> {
    override fun getValue(thisRef: Component, property: KProperty<*>): T =
        MyApp.kodeinInjector.instance<T>().value
}

You should be able to use it like this:

val myInstance by kdi<MyInstanceType>()
elexx commented 7 years ago

Ah ok, so instead of using TornadoFX FX.dicontainer you suggest using my own delegated property (not sure if its called like this, I'm quite new to Kotlin).

Are there any drawbacks if I do dependency injection myself instead of using by di()? Does di() has any sideeffects I have to replicate or anything like this?

edvin commented 7 years ago

There should be no drawbacks to this approach. Third party injection doesn't concern framework components so I don't foresee any issues :) Sorry for the late reply :)