kosi-libs / Kodein

Painless Kotlin Dependency Injection
https://kosi-libs.org/kodein
MIT License
3.21k stars 174 forks source link

Support AndroidX ViewModels with SavedStateHandle in constructor #374

Closed carltonwhitehead closed 3 years ago

carltonwhitehead commented 3 years ago

I'm migrating an Android app from Katana to Kodein DI. I've hit a pain point with the ViewModel factories because some of them take a SavedStateHandle in the constructor.

Katana's SavedStateHandle module made it really simple to delegate instantiation of these to DI. Kodein DI has an androidx module, but no special handling for SavedStateHandle. There is a StackOverflow about this with an older version of Kodein DI, but the accepted solution feels boilerplate-heavy compared to how Katana had addressed this.

API proposal:

class MyViewModel(
    private val state: SavedStateHandle,
    private val someDependency: SomeDependency
) : ViewModel() {
    var someValue: String?
        get() = state.get("SOME_VALUE")
        set(value) {
            state.set("SOME_VALUE", value)
        }
}

DI.Module("example") {
    // long syntax version
    bind<MyViewModel>() with viewModelSavedState { state -> MyViewModel(
        state = state, 
        someDependency = instance()
    ) }

    // short syntax version
    bindViewModelSavedState { state -> MyViewModel(
        state = state, 
        someDependency = instance()
    ) }
}

class MyFragment : Fragment(), DIAware {
    private val viewModel by viewModelSavedState<MyViewModel, MyFragment>() 
}
romainbsl commented 3 years ago

Thank you for your pull request, I will take a deep dive into it this week!