Skip to content

Instantly share code, notes, and snippets.

@code-twister
Last active July 11, 2024 07:55
Show Gist options
  • Save code-twister/b25e46d1538108c82d7cb82d7307a44f to your computer and use it in GitHub Desktop.
Save code-twister/b25e46d1538108c82d7cb82d7307a44f to your computer and use it in GitHub Desktop.
Simple Kotlin Dependency Injection
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
/*
* Using the Injection framework:
*
* Create bindings somewhere in the application before the injections would occur.
*
* factory<MyInterface>(named = "specialName") { SomeImplementation() }
* factory<OtherInterface> { doSomethingHereToCreateAnInstance() }
* single { AnotherClass() }
* single(named = "specialString") { "Something special" }
*
* Use injection:
*
* class SomeClass {
* private val dependency_one by inject<MyInterface>(named = "specialName")
* private val dependency_two: OtherInterface by inject()
* private val anotherClass by inject<AnotherClass>()
* private val test: String by inject(named = "specialString")
* ...
* }
*/
val injectionFactories = mutableMapOf<Pair<KClass<out Any>, String?>, () -> Any>()
inline fun <reified T: Any> inject(named: String? = null) =
object: ReadOnlyProperty<Any, T> {
private val value: T by lazy {
@Suppress("UNCHECKED_CAST")
injectionFactories.getValue(T::class to named).invoke() as T
}
override fun getValue(thisRef: Any, property: KProperty<*>): T = value
}
inline fun <reified T: Any> factory(named: String? = null, noinline block: () -> T) {
injectionFactories[T::class to named] = block
}
inline fun <reified T: Any> single(named: String? = null, noinline block: () -> T) {
block.invoke().let { factory(named) { it } }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment