darkmoon_uk
12/06/2020, 10:58 AMViewModelProvider.Factory
with a lambda that constructs ViewModels with parameters, there is no way to assign this as the default factory. This entails that you either have to pass the factory around your composable functions to use it e.g. by viewModels(myFactory)
or actually override the getDefaultViewModelFactory
method. This is convenient enough in an Activity
but becomes more troublesome if you try to do it for a NavHost
.
In other words the API design is coercing us toward using Dependency Injection frameworks in our ViewModels, rather than just plain construction. Whether you favour DI frameworks or not; construction parameters are objectively the primary mechanism in the Kotlin language for providing dependencies to an object: this at least implies that construction parameters should remain the first and best supported mechanism, followed by others.
Am I missing something here or is there a case for Google to make these API's more flexible?Ian Lake
12/06/2020, 4:09 PMdarkmoon_uk
12/06/2020, 9:14 PMFactory
based on a lambda, that performs custom construction.
What's unclear is how to then use that custom factory in the current framework - besides just invoking it directly.
Ideally I would have this custom factory become part of the default provider, in scope of the current Activity or NavHost.
But there's no way to reassign the default ViewModelProvider
, and looking into the implementation of the default ViewModelProvider
, it doesn't appear to offer any way to have its Factory
reassigned/deferred e.g. one possible way might have the default provider use an ambient factory, using the ambience mechanism?androidx.lifecycle.SavedStateViewModelFactory
which appears to wrap only either of the default AndroidViewModelFactory
or ViewModelFactory
instances, but looks like it could be extended to allow for wrapping a custom ViewModelProvider.Factory
.Ian Lake
12/06/2020, 11:47 PMAbstractSavedStateViewModelFactory
if you want to extend it to allow your own custom create
callsViewModelProvider
/ viewModel()
call. Whether you have a single () -> YourViewModel
lambda you pass into your composable and construct a ViewModelProvider.Factory
out of it via a helper method, whether you pass in an actual ViewModelProvider.Factory
as a parameter to your composable, whether your composable uses an ambient as a bare bones service locator to access your custom factory, or whether you use a full blown DI system to provide either the whole factory or that wraps the construction/creation of the VIewModel up entirely for you (ala what Koin does) is all up to youdarkmoon_uk
12/07/2020, 3:33 AMviewModel(...)
with the factory does still go via the ambient store for caching purposes 👍
Thank you for the guidance.