What DI library are you using with Decompose? Righ...
# decompose
d
What DI library are you using with Decompose? Right now I am using Kodein and I'm not sure if there is a recommended way to do it.
a
Personally I don't use DI frameworks. Though, I created a sample for Dagger - https://github.com/arkivanov/decompose-dagger-sample. For KMP - kotlin-inject should work similarly. Some people are using Koin.
d
Iam using Koin and works perfectly
n
Iam using Koin and works perfectly
@Dennis Out of curiosity, could you make a quick summary on how you instantiate components? I don’t like the way I’m doing it.
d
gratitude thank you 1
j
Following using Decompose and Koin https://github.com/joreilly/Confetti
gratitude thank you 1
n
So the idea is to use
by inject
instead of injecting through the constructor, right?
s
My advice would be to stick to constructor arguments as much as possible. It makes dependencies clearer to the reader, it's easier to write tests for it, it's easier to control dependencies from the outside (by passing it to the object via constructor arguments). So as I do it, • all dependencies are passed into components via the constructor • parents create child components via
Koin.get()
so that parents don't need to know the dependencies of their children. I'm sailing fairly well with this. Simplified it's this:
Copy code
// All Components are also KoinComponents
interface AppComponentContext : ComponentContext, KoinComponent

// Typesafe creator for new components
inline fun <reified Child : ComponentContext> AppComponentContext.getComponent(key: String) =
    get<Child> { parametersOf(childContext(key)) }

class ParentComponent(
    context: ComponentContext
) : AppComponentContext, ComponentContext by context {
    // ...
    
    // same works for ChildStack, etc
    val child = getComponent<ChildComponent>(key = "child") 
}

class ChildComponent(
    context: ComponentContext,
    otherDependency: WidgetFactory // injected by Koin
) : AppComponentContext, ComponentContext by context {
    // ...
}
This simple example lacks a bunch of functionality. For example, it's not possible for the Parent to pass any dependencies explicitly which you probably want to do some time to time; but that can be added with some tricks.
I would avoid a DI framework entirely if it didn't make dependency management that much easier. No idea how @Arkadii Ivanov deals with more complex scenarios where parent and child components need a variety of different dependencies (use cases, services, etc). I couldn't figure it out, so I had use Koin to help 😛
a
In one of my projects I use the same approach as in https://github.com/arkivanov/decompose-dagger-sample, but without a DI framework. So I just writer the code manually that would otherwise generated by Dagger.
So I don't need to write Dagger modules, but I do need a bit of manual wiring (read "calling constructors") on the app side.
Assisted Inject does the trick.
This also lets me have scoped dependencies since I can create a
subDI
for a child component Using it this way, I can add a new dependency for a component and all of its childs, like a composition local
👍 2