Как предоставить ViewModel, который имеет интерфейс через Koin - PullRequest
1 голос
/ 19 февраля 2020

У меня есть следующие настройки ViewModel:

interface FooViewModel {}

class FooViewModelImpl: ViewModel(), FooViewModel {}

, и я хочу предоставить его через Koin следующим образом:

viewModel<FooViewModel> { FooViewModelImpl() }

Это не работает, потому что Koin ожидает ViewModel вместо FooViewModel в определении, и я не хочу делать мой FooViewModel абстрактным классом, который расширяется от ViewModel.

Есть ли способ, которым я могу сделать это через Koin?

1 Ответ

0 голосов
/ 21 марта 2020

Единственный способ заставить его работать - это переопределить функцию расширения 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()

Хотя это возможно, я не думаю, что это хорошая идея, просто хотел поделиться своими выводами. Лучшим способом было бы использовать абстрактный класс (который наследуется от Android ViewModel) вместо интерфейса.

...