Skip to content

Instantly share code, notes, and snippets.

@bmc08gt
Last active June 1, 2022 21:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmc08gt/bcac5e9ab09ef92be3a68fa9147d4874 to your computer and use it in GitHub Desktop.
Save bmc08gt/bcac5e9ab09ef92be3a68fa9147d4874 to your computer and use it in GitHub Desktop.
DIY DI delegate acess
class App : Application() {
override fun onCreate() {
super.onCreate()
ComponentRouter.init(this) {
inject(SomeOtherComponentImpl())
inject(XYComponentImpl())
}
}
}
@MainThread
inline fun <reified C : Component> components(): Lazy<C> {
return ComponentLazy(C::class)
}
class ComponentLazy<C : Component> (
private val componentClass: KClass<C>
) : Lazy<C> {
private var cached: C? = null
override val value: C
get() {
val match = ComponentRouter.components.values.find { it.javaClass.interfaces.contains(componentClass.java) }
requireNotNull(match) {
ComponentNotRegisteredException(componentClass::simpleName)
}
return (match as C).also { cached = it }
}
override fun isInitialized() = cached != null
}
interface Component
object ComponentRouter {
val components: MutableMap<Class<Component>, Component> = mutableMapOf()
fun init(app: Application, block: Initializer.() -> Unit) {
Initializer().apply {
this.inject(AppComponentImpl(app))
block.invoke(this)
}
}
class Initializer {
fun inject(component: Component) {
with(component) {
components[this.javaClass] = component
}
}
}
}
class MainActivity : AppCompatActivity() {
private val appComponent by components<AppComponent>()
[...]
}
@bmc08gt
Copy link
Author

bmc08gt commented Jul 27, 2020

Updated to properly cache the lazy loaded delegate as well as remove required "tagging" of components. Will now use the java class as the tag to prevent multiples of the same component under different names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment