InsertKoinIO / koin

Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
https://insert-koin.io
Apache License 2.0
9.04k stars 718 forks source link

Lazy key for ViewModel #1618

Closed peterdk closed 1 year ago

peterdk commented 1 year ago

Is your feature request related to a problem? Please describe. We need to scope a viewmodel to a certain key in a Fragment. So for Fragments to work properly, they use Bundle with arguments. This means that we can't initialise the viewmodel as follows:

class DialogFragment: Fragment {
companion object {
fun newInstance(viewModelKey: String): DialogFragment {
            val fragment = DialogFragment() // Fails here
            fragment.arguments = bundleOf(ARG_VIEW_MODEL_KEY to viewModelKey)
            return fragment
   }
}

val viewModel by viewModelForClass(
            owner = { requireActivity() },
            key = requireArguments().getString(ARG_VIEW_MODEL_KEY), // This fails because it's already evaluated when DialogFragment() is called
            clazz = SomeViewModel::class,
       )
}

Instead, we need to go this route:

private lateinit var viewModel: SomeViewModel

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel = viewModelForClass(
            owner = { requireActivity() },
            key = requireArguments().getString(ARG_VIEW_MODEL_KEY),
            clazz = SomeViewModel::class,
        ).value
    }

Describe the solution you'd like It would be useful to have the key as a method, just like the owner:

val viewModel by viewModelForClass(
            owner = { requireActivity() },
            key = { requireArguments().getString(ARG_VIEW_MODEL_KEY) },
            clazz = SomeViewModel::class,
       )

Describe alternatives you've considered The one we use now is more verbose. So this would be a bit more clean.

Target Koin project ?

arnaudgiuliani commented 1 year ago

followed in https://github.com/InsertKoinIO/koin/pull/1592