Member-only story
Injecting ViewModel — hard to easy
Comparing Dagger 2, Koin and Service Locator approaches
Architecture Component ViewModel is the way to go for Android Development as advocated by the write up below.
However, there’s one pain point. ViewModel Injection.
To be exact, the pain is not the injection of ViewModel into Activity, but the injection of dependencies into ViewModel.
Let me elaborate.
If you want your ViewModel to be injected into Activity, it is as simple as doing the below
class MyActivity : AppCompatActivity() { private val viewModel: MyViewModel by viewModels() // ...
}
The viewModels()
extension function is provided by androidx KTX . Even if the ViewModel has savedStateHandle
or is taking the intent bundle from the Activity, it doesn’t need to be explicitly injected in. The viewModels()
extension function does all that automatically behind the scene.
However
If you want to inject a ViewModel that has dependencies on various services (e.g. repository), how could one have that inject into the ViewModel?
In order to create ViewModel with SavedStateHandle
, Google provided us some way of doing so with the help of AbstractSavedStateViewModelFactory
. So we’ll need to create Factory for our ViewModel.
An example below where Repository
is the dependencies to be injected into the ViewModel
class MyViewModelFactory(
owner: SavedStateRegistryOwner,
private val repository: Repository,
defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
override fun <T : ViewModel> create(
key: String, modelClass: Class<T>, handle: SavedStateHandle
): T {
return MyViewModel(handle, repository) as T
}
}