Nij*_*dli 7 android interface viewmodel koin
我有以下 ViewModel 设置:
interface FooViewModel {}
class FooViewModelImpl: ViewModel(), FooViewModel {}
Run Code Online (Sandbox Code Playgroud)
我想通过 Koin 提供它,如下所示:
viewModel<FooViewModel> { FooViewModelImpl() }
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为 Koin 在定义中需要 ViewModel 而不是 FooViewModel,而且我不想让我的 FooViewModel 成为从 ViewModel 扩展的抽象类。
有什么办法可以通过 Koin 做到这一点吗?
我让它工作的唯一方法是覆盖 Koin 扩展函数并强制限定符:
ViewModel重写 Koin 模块扩展函数以从其泛型定义中删除:inline fun <reified T> Module.customViewModel(
qualifier: Qualifier? = null,
noinline definition: Definition<T>
): BeanDefinition<T> {
return viewModel(qualifier ?: named(T::class.java.name), definition = definition)
}
inline fun <reified T> Module.viewModel(
qualifier: Qualifier? = null,
override: Boolean = false,
noinline definition: Definition<T>
): BeanDefinition<T> {
val beanDefinition = factory(qualifier, override, definition)
beanDefinition.setIsViewModel()
return beanDefinition
}
Run Code Online (Sandbox Code Playgroud)
inline fun <reified T> LifecycleOwner.customViewModel(
qualifier: Qualifier? = null,
noinline parameters: ParametersDefinition? = null
): Lazy<T> = lazy { getViewModel<ViewModel>(qualifier ?: named(T::class.java.name), parameters) as T }
inline fun <reified T> LifecycleOwner.getCoreViewModel(
qualifier: Qualifier? = null,
noinline parameters: ParametersDefinition? = null
): T = getViewModel<ViewModel>(qualifier ?: named(T::class.java.name), parameters) as T
Run Code Online (Sandbox Code Playgroud)
然后你可以提供 FooViewModel 作为
viewModel<FooViewModel> { FooViewModelImpl() }
Run Code Online (Sandbox Code Playgroud)
并将其注入为:
private val viewModel: FooViewModel by customViewModel()
// or
val viewModel: FooViewModel = getCustomViewModel()
Run Code Online (Sandbox Code Playgroud)
虽然这是可能的,但我认为这不是一个好主意,只是想分享我的发现。最好的方法是使用抽象类(继承自 Android ViewModel)而不是接口。