我正在开发一个Jetpack Compose应用程序,并使用Dagger-Hilt进行依赖注入。我有两个ViewModel(MainViewModel和FormViewModel)从单个AppRepository订阅StateFlow。两个ViewModel都正确初始化,但只有MainViewModel从存储库接收更新,而FormViewModel没有。两个示例都是在相同的组合和时间创建的。
备注:这个应用程序是我使用Jetpack Compose和MVVM模式开发的最广泛的应用程序。(目前约800行),并仍在扩大。值得注意的是,此ViewModel的很大一部分(大约一半)是专门用于处理表单的。我的目标是将这些与表单相关的代码重构为一个单独的ViewModel,我不确定这种方法是否符合使用MVVM和Dagger-Hilt的最佳实践。维护一个单一的大型ViewModel是明智的,还是可以接受将功能拆分为多个ViewModel以获得更好的模块化和可维护性?
AppRepository(摘要):
@Singleton
class AppRepository @Inject constructor(...) {
private val _services = MutableStateFlow<List<LocalService>>(listOf())
val services: StateFlow<List<LocalService>> = _services
..
}
字符串
主视图模型:
@HiltViewModel
class MainViewModel @Inject constructor(
private val appRepository: AppRepository,
private val application: Application
) : ViewModel() {
val services: StateFlow<List<LocalService>> = appRepository.services
init {
viewModelScope.launch {
services.collect { ... // Logs to print services.size
}
}
}
}
型
FormViewModel:
@HiltViewModel
class FormViewModel @Inject constructor(private val appRepository: AppRepository) : ViewModel() {
val services: StateFlow<List<LocalService>> = appRepository.services
init {
viewModelScope.launch {
services.collect { ... // Logs to print services.size
}
}
}
}
型
模块:
@Module
@InstallIn(SingletonComponent::class)
object Module {
...
@Provides
fun provideMainRepository(
...
): AppRepository {
return AppRepository(
...
)
}
型
2023-11-14 11:31:16.170 15406-15406 FormViewModel com.conecta D MainViewModel init
2023-11-14 11:31:16.172 15406-15406 FormViewModel com.conecta D MainViewModel formQuestionCrossRef has changed: 0
2023-11-14 11:31:16.173 15406-15406 FormViewModel com.conecta D MainViewModel serviceFormCrossRef has changed: 0
2023-11-14 11:31:16.174 15406-15406 FormViewModel com.conecta D MainViewModel services has changed: 0
2023-11-14 11:31:16.757 15406-15406 FormViewModel com.conecta D FormViewModel init
2023-11-14 11:31:16.758 15406-15406 FormViewModel com.conecta D FormViewModel formQuestionCrossRef has changed: 0
2023-11-14 11:31:16.759 15406-15406 FormViewModel com.conecta D FormViewModel serviceFormCrossRef has changed: 0
2023-11-14 11:31:16.760 15406-15406 FormViewModel com.conecta D FormViewModel services has changed: 0
2023-11-14 11:31:20.028 15406-15406 FormViewModel com.conecta D MainViewModel services has changed: 30
2023-11-14 11:31:20.270 15406-15406 FormViewModel com.conecta D MainViewModel formQuestionCrossRef has changed: 1260
2023-11-14 11:31:20.274 15406-15406 FormViewModel com.conecta D MainViewModel serviceFormCrossRef has changed: 90
型
2条答案
按热度按时间n9vozmp41#
你不需要在模块中为
AppRepository
使用@Provides
方法。这样,dagger就有两种方法来创建AppRepository
的示例--它的@Inject
注解构造函数和@Provides
方法。老实说,我不确定最后哪种方法会赢,但我很确定问题是你有多个仓库示例。此外,安装在
SingletonComponent
中的模块中的@Provides
方法并不意味着dagger将只创建该类的一个示例。为此,您必须使用@Singleton
注解方法本身。从docs:警告:一个常见的误解是,在模块中声明的所有绑定都将作用于安装该模块的组件。然而,这不是真的。只有用范围注解注解的绑定声明才是作用域。
这意味着有两种可能的解决方案:
1.删除
@Provides fun provideMainRepository()
1.从
AppRepository
中删除@Inject
和@Singleton
,并将@Singleton
添加到provideMainRepository()
x759pob22#
关于应用程序架构-你可能需要一个Domain layer。它将允许你: