我有两个ViewModels
,它们依赖于其他对象,而这些对象又可能依赖于context
(SettingsDataStore
).现在,为了将context
排除在我的视图模型之外,我遵循inversion of control
原则.
我的代码如下所示:
// MainActivity.kt
private val Context.dataStore by preferencesDataStore(name = "settings")
val newsRepository = NewsRepository()
val newsDetailViewModel = NewsDetailViewModel()
lateinit var newsViewModel: NewsViewModel
lateinit var settingsViewModel: SettingsViewModel
@Composable
fun Navigation() {
val context = LocalContext.current
val settingsDataStore = SettingsDataStore(context.dataStore)
if (!::settingsViewModel.isInitialized) {
settingsViewModel = viewModel(initializer = { SettingsViewModel(settingsDataStore) })
}
if (!::newsViewModel.isInitialized) {
newsViewModel =
viewModel(initializer = { NewsViewModel(newsRepository, settingsDataStore) })
}
...
如您所见,我在Composable函数中创建了SettingsDataStore
,因为我需要访问context
.然后,我将使用它们的依赖项构造ViewModels
.However, I suspect this kind of injection is faulty because of plenty of reasons -- invalidation of the context and accidental creation of ViewModels if you are not careful comes to mind.
因此,我做了一些研究,发现这篇文章的official docs条推荐使用ViewModelProvider.Factory
.不幸的是,我不知道如何使用工厂正确地创建我的NewsViewModel
:
class NewsViewModel(
private val repo: NewsRepository,
private val settingsDataStore: SettingsDataStore
) : ViewModel() {
...
// Define ViewModel factory in a companion object
companion object {
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
// Get the Application object from extras
val application = checkNotNull(extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY])
// Create a SavedStateHandle for this ViewModel from extras
val savedStateHandle = extras.createSavedStateHandle()
return NewsViewModel(
// TODO HOW DO I ACCESS/CREATE THE DEPENDENCIES ??
) as T
}
}
}
}
所以我的问题是how do I create my 100 with that factory?我想坚持使用Android文档,而不是使用某种依赖注入框架.
很抱歉问了这么长的问题,但我想要详细说明,因为很多遵循适当MVVM架构的人都会遇到这个问题.