Kotlin中如何在Kodein中配置多ViewModel的ViewModelFactory
解决Kodein中多ViewModelFactory的集中配置问题
你可以通过通用ViewModelFactory来避免为每个ViewModel单独创建Factory类,所有配置都能集中在Application的Kodein代码块里,具体实现如下:
1. 编写通用ViewModelFactory类
这个工厂类接受一个ViewModel的构造函数引用,负责创建对应的ViewModel实例,无需为每个ViewModel重复编写Factory:
class GenericViewModelFactory<VM : ViewModel>( private val viewModelProducer: () -> VM ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel> create(modelClass: Class<T>): T { return viewModelProducer() as T } }
2. 在Kodein中集中配置所有ViewModel的工厂
在Application的Kodein懒加载块里,直接为每个ViewModel绑定对应的通用工厂,无需单独创建Factory类:
class AddSpendApplication: Application(), KodeinAware { override val kodein: Kodein = Kodein.lazy { import(androidXModule(this@AddSpendApplication)) // 绑定基础依赖 bind() from singleton { PersonalAccountingDateBase(instance()) } bind() from singleton { AddSpendRepository(instance()) } // 示例:添加另一个仓库依赖 bind() from singleton { StatisticsRepository(instance()) } // 为AddSpendViewModel绑定通用工厂 bind<ViewModelProvider.Factory>() with provider { GenericViewModelFactory { AddSpendViewModel(instance<AddSpendRepository>()) } } // 为StatisticsViewModel绑定通用工厂,通过命名区分不同工厂 bind<ViewModelProvider.Factory>("StatisticsViewModelFactory") with provider { GenericViewModelFactory { StatisticsViewModel(instance<StatisticsRepository>()) } } } }
3. 在页面中获取对应的ViewModel
- 对于默认绑定的ViewModel(如AddSpendViewModel),直接通过
viewModel()委托获取:
class AddSpendActivity : AppCompatActivity(), KodeinAware { override val kodein by closestKodein() private val viewModel: AddSpendViewModel by viewModel() // 页面逻辑代码 }
- 对于带命名的工厂(如StatisticsViewModel),指定工厂名称即可:
class StatisticsActivity : AppCompatActivity(), KodeinAware { override val kodein by closestKodein() private val viewModel: StatisticsViewModel by viewModel(factoryName = "StatisticsViewModelFactory") // 页面逻辑代码 }
这种方式既满足了集中编写Application代码的需求,又避免了大量重复的ViewModelFactory类,同时保持了Kodein依赖注入的灵活性。
内容的提问来源于stack exchange,提问作者M.Shaker Nayyal
相关产品推荐
相关产品推荐

