I have the following ViewModel setup:
interface FooViewModel {}
class FooViewModelImpl: ViewModel(), FooViewModel {}
and I want to provide it via Koin like this:
viewModel<FooViewModel> { FooViewModelImpl() }
It doesn't work because Koin expects ViewModel instead of FooViewModel in the definition and I don't want to make my FooViewModel an abstract class that extends from ViewModel.
Is there a way I can do this via Koin?
The only way I got it working was to override Koin extension function and enforce qualifier:
ViewModel
from its generics definition: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
}
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
Then you can provide FooViewModel as
viewModel<FooViewModel> { FooViewModelImpl() }
and inject it as:
private val viewModel: FooViewModel by customViewModel()
// or
val viewModel: FooViewModel = getCustomViewModel()
Although this is possible I don't think it is a good idea, just wanted to share my findings. The best way would be to use abstract class (which inherits from Android ViewModel
) instead of an interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With