Коин Область и интерфейс
Я использую библиотеку Коин ди в своем проекте. Версия lib - 1.0.0-RC-1.
Мой модуль:
val appModule = module {
scope("UserScope") { UserToaster(androidContext()) as Toaster }
scope("AnonScope") { AnonToaster(androidContext()) as Toaster }
}
Я запустил koin в своем классе 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.
Я не понимаю, почему это не работает (если использовать сингл с разными именами - это будет работать). Это ошибка Коина? Как избежать этой ошибки?
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))
Ваши определения имеют одно и то же имя в коине. Текущая версия (~1.0.*) Позволяет вам не указывать, какую область использовать, благодаря автоматическому разрешению типа и его идентификатора сеанса.
Можете ли вы избежать описания ваших определений с таким же типом, как:
val appModule = module {
scope("UserScope") { UserToaster(androidContext()) }
scope("AnonScope") { AnonToaster(androidContext()) }
}
В противном случае нам понадобится возможность указать, какую область использовать при разрешении типа. Вы бы решили это с помощью:
val userScope = getScope("UserScope")
get<Toaster>(scope = userScope)