The only way I got it working was to override Koin extension function and enforce qualifier:
- Override Koin Module extension function to drop
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
}
- Override Koin LifecycleOwner extension functions same way:
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.