Skip to content

Instantly share code, notes, and snippets.

@LuizTM
Last active June 11, 2025 06:08
Show Gist options
  • Save LuizTM/c1c6c704ab444e54bcf1fd336a1053bf to your computer and use it in GitHub Desktop.
Save LuizTM/c1c6c704ab444e54bcf1fd336a1053bf to your computer and use it in GitHub Desktop.
Kotlin DI Scratch
package com.luiztm.ui.dependency
import kotlin.reflect.KClass
//interface Analytics
interface Analytics {
fun doSomething(): String
}
fun Map<String, () -> Any>.injectAnalytics(): Lazy<Analytics> = lazy {
this[Analytics::class.java.name]?.invoke() as Analytics
}
fun ((KClass<*>) -> Any).injectAnalytics(): Lazy<Analytics> = lazy {
this.invoke(Analytics::class) as Analytics
}
//
//interface Cache
interface Cache {
fun doSomething(): String
}
fun Map<String, () -> Any>.injectCache(): Lazy<Cache> = lazy {
this[Cache::class.java.name]?.invoke() as Cache
}
fun ((KClass<*>) -> Any).injectCache(): Lazy<Cache> = lazy {
this.invoke(Cache::class) as Cache
}
//
//Main Application
typealias FactoryType = () -> Any
typealias FactoryType2 = (KClass<*>) -> Any
interface Factory : Map<String, FactoryType>
interface Factory2 : FactoryType2
class FactoryImpl(
items: Map<String, FactoryType> =
mapOf(
Analytics::class.java.name to {
object : Analytics {
override fun doSomething() = "Hello Analytics"
}
},
Cache::class.java.name to {
object : Cache {
override fun doSomething() = "Hello Cache"
}
},
)
) : Factory, Map<String, FactoryType> by items
class FactoryImpl2 : Factory2 {
override fun invoke(kClass: KClass<*>): Any {
return when (kClass) {
Analytics::class -> object : Analytics {
override fun doSomething() = "Hello Analytics 2"
}
Cache::class -> object : Cache {
override fun doSomething() = "Hello Cache 2"
}
else -> throw IllegalArgumentException("some message error here!")
}
}
}
object Application :
Factory by FactoryImpl(),
Factory2 by FactoryImpl2()
// Main Application
// inside feature module
class Feature {
private val context = Application as Map<String, FactoryType>
private val context2 = Application as as ((KClass<*>) -> Any)
val cache: Cache by context.injectCache()
val analytics: Analytics by context.injectAnalytics()
val analytics2: Analytics by context2.injectAnalytics()
val cache2: Cache by context2.injectCache()
}
fun main() {
val feat = Feature()
println(feat.cache.doSomething())
println(feat.analytics.doSomething())
println(feat.cache2.doSomething())
println(feat.analytics2.doSomething())
}
// inside feature module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment