KolinLoures
KolinLoures

Reputation: 130

Koin Scope and Interface

I am using Koin di library in my project. Version of lib is 1.0.0-RC-1.

My module:

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

I started koin in my Application class and created scope:

override fun onCreate() {
    super.onCreate()

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

And next I tried to inject implementation of Toaster from current scope to variable in Activity. Here the code:

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

After this I got an error:

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.

I do not understand why this does not work (If use single with different names - it will work). Is that koin bug? How to avoid this error?

Upvotes: 6

Views: 5108

Answers (2)

Vitali
Vitali

Reputation: 854

I implemented it like this

Module:

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 }
}

Main Activity:

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

AuthActivity:

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

Upvotes: 3

Arnaud Giuliani
Arnaud Giuliani

Reputation: 91

your definitions have the same name in Koin. Current version (~1.0.*) avoid you to specify which scope to use, by automating resolving a type and it's session id.

Can you avoid describe your definitions with same type, like:

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

Else we would need a feature to specify which scope to use when resolving a type. You would resolve it with:

val userScope = getScope("UserScope")
get<Toaster>(scope = userScope)

Upvotes: 0

Related Questions