Using Scopes

Koin brings a simple API to let you define instances that are tied to a limit lifetime.

What is a scope?

Scope is a fixed duration of time or method calls in which an object exists. Another way to look at this is to think of scope as the amount of time an object’s state persists. When the scope context ends, any objects bound under that scope cannot be injected again (they are dropped from the container).

Scope definition

By default in Koin, we have 3 kind of scopes:

  • single definition, create an object that persistent with the entire container lifetime (can’t be dropped).

  • factory definition, create a new object each time. Short live. No persistence in the container (can’t be shared).

  • scoped definition, create an object that persistent tied to the associated scope lifetime.

To declare a scoped definition, use the scoped function like follow. A scope gathers scoped definitions as a logical unit of time:

module {
    scope(named("A Scope Name")){
        scoped { Presenter() }
        // ...
    }
}

Working with a scope

A scope instance can be created with as follow: val scope = koin.createScope("myScope"). The "myScope" string here, is the id of your scope instance.

To resolve a dependency using the scope we can do it like:

  • val presenter = scope.get<Presenter>() - directly using the get/inject functions from the scope instance

We have to declare a the scope instance like follow:

// create scope instance "myScope" (the scope Id) for scope "A_SCOPE_NAME" (the qualifier)
val scope = koin.createScope("myScope","A_SCOPE_NAME")
// resolve presenter instance
val presenter = scope.get<Presenter>()

Create & retrieve a scope

From a KoinComponent class or where you can access your Koin instance:

  • createScope(id : ScopeID, scopeName : Qualifier) - create a closed scope instance with given id and scopeName

  • getScope(id : ScopeID) - retrieve a previously created scope with given id

  • getOrCreateScope(id : ScopeID, scopeName : Qualifier) - create or retrieve if already created, the closed scope instance with given id and scopeName

Important

Make the difference between a scope instance id, which is the id to find your scope over all your scopes, and the scope name, which is the reference to the tied scope group name.

Creating scope instances

Using the id, it’s then possible to have several instances of the same scope:

// create an closed scope instance "myScope1" for scope "A_SCOPE_NAME"
val myScope1 = koin.createScope("myScope1",named("A_SCOPE_NAME"))
// create an closed scope instance "myScope2" for scope "A_SCOPE_NAME"
val myScope2 = koin.createScope("myScope2",named("A_SCOPE_NAME"))

Resolving dependencies within a scope

The interest of a scope is to define a common logical unit of time for scoped definitions. It’s allow also to resolve definitions from within the given scope

// given the classes
class ComponentA
class ComponentB(val a : ComponentA)

// module with scope
module {

    scope(named("A_SCOPE_NAME")){
        scoped { ComponentA() }
        // will resolve from current scope instance
        scoped { ComponentB(get()) }
    }
}

The dependency resolution is then straight forward:

// create an closed scope instance "myScope1" for scope "A_SCOPE_NAME"
val myScope1 = koin.createScope("myScope1",named("A_SCOPE_NAME"))

// from the same scope
val componentA = myScope1.get<ComponentA>()
val componentB = myScope1.get<ComponentB>()

Closing a scope

Once your scope instance is finished, just closed it with the close() function:

// from a KoinComponent
val session = getKoin().createScope("session")

// use it ...

// close it
session.close()
Important

Beware that you can’t inject instances anymore from a closed scope.

Scope callback — TODO