daugeldauge / kinzhal

Compile-time dependency injection for Kotlin Multiplatform

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support assisted injection

vganin opened this issue · comments

It would be convenient with library such as Decompose. Decompose Components are created by hand in factory lambda and must be initialized with ComponentContext provided from parent.

I'll demonstrate with example. Here what we must do with Decompose without auto DI

class RootComponent(
    componentContext: ComponentContext
) : ComponentContext by componentContext {

    val navigation = StackNavigation<Config>()

    val stack =
        childStack(
            source = navigation,
            initialConfiguration = Config.List,
            handleBackButton = true,
            childFactory = ::createChild,
        )

    fun createChild(config: Config, componentContext: ComponentContext): ComponentContext =
        // Here we must use provided componentContext to create child component
        when (config) {
            is Config.List -> ListComponent(componentContext, ???) // Where to get depA, depB, depC, etc.???
            is Config.Details -> // ...
        }

    sealed class Config : Parcelable {
        @Parcelize
        object List : Config()

        @Parcelize
        data class Details(val itemId: Long) : Config()
    }
}

class ListComponent(
    componentContext: ComponentContext,
    depA: DepA,
    depB: DepB,
    depC: DepC,
    // ...
) : ComponentContext by componentContext {
    // ...
} 

We can improve this example with assisted injection like so

class RootComponent @Inject constructor(
    componentContext: ComponentContext,
    listComponentFactory: ListComponentFactory,
    // Rest component factories
) : ComponentContext by componentContext {

    val navigation = StackNavigation<Config>()

    val stack =
        childStack(
            source = navigation,
            initialConfiguration = Config.List,
            handleBackButton = true,
            childFactory = ::createChild,
        )

    fun createChild(config: Config, componentContext: ComponentContext): ComponentContext =
        when (config) {
            is Config.List -> listComponentFactory.create(componentContext)
            is Config.Details -> // ...
        }
}

@AssistedFactory
interface ListComponentFactory {
    fun create(componentContext: ComponentContext): ListComponent
} 

class ListComponent @AssistedInject constructor(
    @Assisted componentContext: ComponentContext,
    depA: DepA,
    depB: DepB,
    depC: DepC,
    // ...
) : ComponentContext by componentContext {
    // ...
}

Could you please release this change? Hopefully this project is still maintained.

@ber4444 I'll publish a release next weekend. Thanks for the interest in the library :)