Объем и интерфейс Koin

Я использую в своем проекте библиотеку Koin di. Версия библиотеки: 1.0.0-RC-1.

Мой модуль:

val appModule = module {
    scope("UserScope") { UserToaster(androidContext()) as Toaster }
    scope("AnonScope") { AnonToaster(androidContext()) as Toaster }
}

Я запустил коин в своем классе Application и создал область:

override fun onCreate() {
    super.onCreate()

    startKoin(this, listOf(appModule))
    getKoin().getOrCreateScope("AnonScope")
}

Затем я попытался внедрить реализацию Toaster из текущей области видимости в переменную Activity. Вот код:

private val toaster: Toaster by inject(scope = "AnonScope")

После этого у меня появилась ошибка:

Caused by: org.koin.error.DependencyResolutionException: Multiple definitions found for type 'interface com.example.nkirilov.playground.Toaster (Kotlin reflection is not available)' - Koin can't choose between :
    Scope [name='UserScope',class='com.example.nkirilov.playground.Toaster']
    Scope [name='AnonScope',class='com.example.nkirilov.playground.Toaster']
    Check your modules definition, use inner modules visibility or definition names.

Не понимаю, почему это не работает (если использовать single с разными именами - сработает). Это ошибка коина? Как избежать этой ошибки?


person KolinLoures    schedule 07.09.2018    source источник


Ответы (2)


Я реализовал это так

Модуль:

val navigationModule = module {
    scope(DI.APP_SCOPE) { ClassA().create }
    scope(DI.APP_SCOPE) { get(scopeId = DI.APP_SCOPE).classB }
    scope(DI.APP_SCOPE) { get(scopeId = DI.APP_SCOPE).classC }
}

val authModule = module {
    scope(DI.AUTH_SCOPE) { ClassA.create(ChildClassB(get(scopeId = DI.APP_SCOPE))) }
    scope(DI.AUTH_SCOPE) { get(scopeId = DI.AUTH_SCOPE).classB }
    scope(DI.AUTH_SCOPE) { get(scopeId = DI.AUTH_SCOPE).classC }
}

Основная деятельность:

private val classC: ClassC by inject(scope = getKoin().getOrCreateScope(APP_SCOPE))

AuthActivity:

private val classC: ClassC by inject(scope = getKoin().getOrCreateScope(DI.AUTH_SCOPE))
person Vitali    schedule 11.10.2018

ваши определения имеют то же имя в Koin. Текущая версия (~ 1.0. *) Позволяет вам не указывать, какую область использовать, автоматизируя определение типа и его идентификатора сеанса.

Можете ли вы не описывать свои определения одним и тем же типом, например:

val appModule = module {
    scope("UserScope") { UserToaster(androidContext()) }
    scope("AnonScope") { AnonToaster(androidContext()) }
}

В противном случае нам понадобится функция, чтобы указать, какую область использовать при разрешении типа. Вы бы разрешили это с помощью:

val userScope = getScope("UserScope")
get<Toaster>(scope = userScope)
person Arnaud Giuliani    schedule 07.09.2018
comment
У меня не получилось. Я создал образец проекта на Github, если вы будете свободны, проверьте, пожалуйста. [Вот ссылка:] (github.com/KolinLoures/TestScopeKoin). TIA - person KolinLoures; 09.09.2018
comment
позволь мне проверить это ???? - person Arnaud Giuliani; 10.09.2018
comment
отредактировал мой комментарий. Можете ли вы прямо сейчас использовать ваши типы? - person Arnaud Giuliani; 10.09.2018
comment
К сожалению, не могу. В моем рабочем проекте мне нужно настроить реализацию в соответствии с созданным объемом. Может быть, есть другой подход к реализации этой идеи? - person KolinLoures; 10.09.2018
comment
Можно использовать это: getKoin (). Get ‹Toaster› (clazz = Toaster :: class, filter = {a: BeanDefinition ‹*› - ›a.attributes [scope] == currentScope.id}) - person KolinLoures; 12.09.2018
comment
Немного сложно найти это в таком виде, но главное, чтобы видимость не ограничивалась прицелом. Вы можете поднять вопрос на github. - person Arnaud Giuliani; 12.09.2018