DI
The default dependency injection graph.
This supplements purely code-based DI solutions (which use by lazy
instead of @Singleton
etc.) by tracking the interdependencies between the DI nodes and re-creating sub-graphs whenever a DI object is replaced dynamically (e.g. because the app wants to reconfigure itself).
Example how to define a code-based DI graph:
// -------------
// module foo
// -------------
// Convenience accessor for FooDeps
val DIResolver.fooDeps: LazyProperty<FooDeps> get() = DI.run { get() }
// The actual FooDeps DI module/node. This is a circular dependency with BarDeps below.
class FooDeps(
val configFlag: Boolean,
lazyBarDeps: LazyProperty<BarDeps>,
) {
// All deps have to be resolved lazily
val barDeps by lazyBarDeps
// All deps have to be resolved lazily
val circularConfigFlag by lazy { barDeps.configFlag }
public fun myUseCase() = MyUseCase(circularConfigFlag)
}
class MyUseCase(val circularConfigFlag: Boolean)
// -------------
// module bar
// -------------
// Convenience accessor for BarDeps
val DIResolver.barDeps: LazyProperty<BarDeps> get() = DI.run { get() }
// Circular dependency to Foo, so we have
class BarDeps(lazyFooDeps: LazyProperty<FooDeps>) {
val fooDeps: FooDeps by lazyFooDeps
val configFlag: Boolean by lazy { fooDeps.configFlag }
}
Content copied to clipboard