docs/reference/koin-annotations/scope.md
While using definitions and modules, you may need to define scopes for a particular space and time resolution.
Koin allows the use of scopes. Please refer to Koin Scopes section for more details on basics.
To declare a scope with annotations, just use @Scope annotation on a class, like this
@Scope
class MyScopeClass
this will be equivalent of the following scope section:
kotlinscope<MyScopeClass> { }
Else, if you need a scope name more than a type, you need to tag a class with @Scope(name = ) annotation, using name parameter:
@Scope(name = "my_scope_name")
class MyScopeClass
this will be the equivalent of
kotlinscope<named("my_scope_name")> { }
To declare a definition inside a scope (defined or not with annotations), just tag a class with @Scope and @Scoped annotations:
@Scope(name = "my_scope_name")
@Scoped
class MyScopedComponent
This will generate the right definition inside the scope section:
scope<named("my_scope_name")> {
scoped { MyScopedComponent() }
}
:::info
You need both annotations to indicate the needed scope space (with @Scope) and the kind of component to define (with @Scoped)
:::
From a scoped definition, you can resolve any definition from your inner Scope and from the parent scopes.
For example, the following case will work:
@Single
class MySingle
@Scope(name = "my_scope_name")
@Scoped
class MyScopedComponent(
val mySingle : MySingle,
val myOtherScopedComponent :MyOtherScopedComponent
)
@Scope(name = "my_scope_name")
@Scoped
class MyOtherScopedComponent(
val mySingle : MySingle
)
The component MySingle is defined as single definition, in the root. MyScopedComponent and MyOtherScopedComponent are defined in scope "my_scope_name".
The dependencies resolution from MyScopedComponent is accessing the Koin root with MySingle instance, and MyOtherScopedComponent scoped instance from the current "my_scope_name" scope.
You may need to resolve a component from another scope that is not directly accessible to your scope. For this, you need to tag your dependency with @ScopeId annotation to tell Koin to find this dependency in the scope of the given scope Id.
@Factory
class MyFactory(
@ScopeId("my_scope_id") val myScopedComponent :MyScopedComponent
)
The above code is equivalent is generated:
factory { Myfactory(getScope("my_scope_id").get()) }
This example shows that MyFactory component will resolve MyScopedComponent component from a scope instance with id "my_scope_id". This scope, created with id "my_scope_id" needs to be created with the right scope definition.
:::info
The MyScopedComponent component needs to be defined in a Scope section, and a scope instance needs to be created with id "my_scope_id".
:::
Koin Annotations provides predefined scope archetype annotations for common scope patterns, eliminating the need to manually declare scope types. These annotations combine scope declaration and component definition in a single annotation.
For Android development, you can use these predefined scope annotations:
Declare a component in an Activity scope:
@ActivityScope
class ActivityScopedComponent(val dependency: MyDependency)
This generates:
activityScope {
scoped { ActivityScopedComponent(get()) }
}
Usage: The tagged class is meant to be used with Activity and the activityScope function to activate the scope.
Declare a component in an Activity Retained scope (survives configuration changes):
@ActivityRetainedScope
class RetainedComponent(val repository: MyRepository)
This generates:
activityRetainedScope {
scoped { RetainedComponent(get()) }
}
Usage: The tagged class is meant to be used with Activity and the activityRetainedScope function to activate the scope.
Declare a component in a Fragment scope:
@FragmentScope
class FragmentScopedComponent(val service: MyService)
This generates:
fragmentScope {
scoped { FragmentScopedComponent(get()) }
}
Usage: The tagged class is meant to be used with Fragment and the fragmentScope function to activate the scope.
Declare a component in a ViewModel scope. This annotation is Kotlin Multiplatform (KMP) compatible and works with both Android ViewModels and Compose Multiplatform ViewModels:
@ViewModelScope
class ViewModelScopedRepository(val apiService: ApiService)
@ViewModelScope
class ViewModelScopedUseCase(
val repository: ViewModelScopedRepository,
val analytics: AnalyticsService
)
This generates:
viewModelScope {
scoped { ViewModelScopedRepository(get()) }
scoped { ViewModelScopedUseCase(get(), get()) }
}
Usage: The tagged class is meant to be used with ViewModel and the viewModelScope function to activate the scope.
KMP Support: Works seamlessly across all Kotlin Multiplatform targets including Android, iOS, Desktop, and Web platforms where ViewModels are used.
Scope archetype annotations work seamlessly with regular Koin scoping:
// Regular components
@Single
class GlobalService
// Scoped components using archetypes
@ActivityScope
class ActivityService(val global: GlobalService)
@FragmentScope
class FragmentService(
val global: GlobalService,
val activity: ActivityService
)
Scope archetypes can also be used on functions within modules:
@Module
class MyModule {
@ActivityScope
fun activityComponent(dep: MyDependency) = MyActivityComponent(dep)
@FragmentScope
fun fragmentComponent(dep: MyDependency) = MyFragmentComponent(dep)
}
:::info Scope archetype annotations automatically create the appropriate scope definition and scoped component declaration, reducing boilerplate code for common scope patterns. :::