如何通过 Koin 提供具有接口的 ViewModel
How to provide ViewModel that has interface via Koin
我有以下 ViewModel 设置:
interface FooViewModel {}
class FooViewModelImpl: ViewModel(), FooViewModel {}
我想像这样通过 Koin 提供它:
viewModel<FooViewModel> { FooViewModelImpl() }
它不起作用,因为 Koin 期望在定义中使用 ViewModel 而不是 FooViewModel,并且我不想使我的 FooViewModel 成为从 ViewModel 扩展的抽象 class。
我可以通过 Koin 做到这一点吗?
我让它工作的唯一方法是覆盖 Koin 扩展函数并强制执行限定符:
- 覆盖 Koin 模块扩展函数以从其泛型定义中删除
ViewModel
:
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
}
- 以相同的方式覆盖 Koin LifecycleOwner 扩展函数:
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
然后你可以提供 FooViewModel 作为
viewModel<FooViewModel> { FooViewModelImpl() }
并将其注入为:
private val viewModel: FooViewModel by customViewModel()
// or
val viewModel: FooViewModel = getCustomViewModel()
虽然这是可能的,但我认为这不是一个好主意,只是想分享我的发现。最好的方法是使用抽象 class(继承自 Android ViewModel
)而不是接口。
我有以下 ViewModel 设置:
interface FooViewModel {}
class FooViewModelImpl: ViewModel(), FooViewModel {}
我想像这样通过 Koin 提供它:
viewModel<FooViewModel> { FooViewModelImpl() }
它不起作用,因为 Koin 期望在定义中使用 ViewModel 而不是 FooViewModel,并且我不想使我的 FooViewModel 成为从 ViewModel 扩展的抽象 class。
我可以通过 Koin 做到这一点吗?
我让它工作的唯一方法是覆盖 Koin 扩展函数并强制执行限定符:
- 覆盖 Koin 模块扩展函数以从其泛型定义中删除
ViewModel
:
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
}
- 以相同的方式覆盖 Koin LifecycleOwner 扩展函数:
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
然后你可以提供 FooViewModel 作为
viewModel<FooViewModel> { FooViewModelImpl() }
并将其注入为:
private val viewModel: FooViewModel by customViewModel()
// or
val viewModel: FooViewModel = getCustomViewModel()
虽然这是可能的,但我认为这不是一个好主意,只是想分享我的发现。最好的方法是使用抽象 class(继承自 Android ViewModel
)而不是接口。