0
# Scope Management
1
2
Scoped dependency lifecycles for managing instances with controlled lifecycles and isolation.
3
4
## Capabilities
5
6
### Scope Creation
7
8
Create and manage scoped containers for isolated dependency lifecycles.
9
10
```kotlin { .api }
11
/**
12
* Create a new scope with qualifier and optional source
13
* @param scopeId - Unique identifier for the scope
14
* @param qualifier - Scope qualifier defining the scope type
15
* @param source - Optional source object associated with the scope
16
* @param scopeArchetype - Optional scope archetype for additional typing
17
* @return New Scope instance
18
*/
19
fun Koin.createScope(scopeId: ScopeID, qualifier: Qualifier, source: Any? = null, scopeArchetype: TypeQualifier? = null): Scope
20
21
/**
22
* Create a new scope with type qualifier
23
* @param scopeId - Unique identifier for the scope
24
* @param source - Optional source object associated with the scope
25
* @param scopeArchetype - Optional scope archetype for additional typing
26
* @return New Scope instance
27
*/
28
inline fun <reified T : Any> Koin.createScope(scopeId: ScopeID, source: Any? = null, scopeArchetype: TypeQualifier? = null): Scope
29
30
/**
31
* Create a new scope with generated ID
32
* @param scopeId - Unique identifier for the scope (default: generated)
33
* @return New Scope instance
34
*/
35
inline fun <reified T : Any> Koin.createScope(scopeId: ScopeID = KoinPlatformTools.generateId()): Scope
36
37
/**
38
* Create a scope for a KoinScopeComponent
39
* @param t - Component to create scope for
40
* @return New Scope instance associated with the component
41
*/
42
fun <T : KoinScopeComponent> Koin.createScope(t: T): Scope
43
```
44
45
**Usage Examples:**
46
47
```kotlin
48
import org.koin.core.context.startKoin
49
import org.koin.core.qualifier.named
50
import org.koin.dsl.module
51
52
// Define scoped services
53
class RequestContext
54
class UserSession(val userId: String)
55
class RequestProcessor(private val context: RequestContext, private val session: UserSession)
56
57
// Module with scoped definitions
58
val webModule = module {
59
scope(named("request")) {
60
scoped { RequestContext() }
61
factory { (userId: String) -> UserSession(userId) }
62
scoped { RequestProcessor(get(), get()) }
63
}
64
}
65
66
startKoin { modules(webModule) }
67
68
// Create scopes
69
val requestScope = koin.createScope("req-123", named("request"))
70
val typedScope = koin.createScope<RequestScope>("req-456")
71
72
// Use scoped dependencies
73
val processor = requestScope.get<RequestProcessor> { parametersOf("user-789") }
74
```
75
76
### Scope Retrieval
77
78
Get existing scopes or create them if they don't exist.
79
80
```kotlin { .api }
81
/**
82
* Get or create a scope with the given ID and qualifier
83
* @param scopeId - Scope identifier
84
* @param qualifier - Scope qualifier
85
* @param source - Optional source object
86
* @return Existing scope or new scope if not found
87
*/
88
fun Koin.getOrCreateScope(scopeId: ScopeID, qualifier: Qualifier, source: Any? = null): Scope
89
90
/**
91
* Get or create a scope with type qualifier
92
* @param scopeId - Scope identifier
93
* @return Existing scope or new scope if not found
94
*/
95
inline fun <reified T : Any> Koin.getOrCreateScope(scopeId: ScopeID): Scope
96
97
/**
98
* Get an existing scope by ID
99
* @param scopeId - Scope identifier
100
* @return Existing scope
101
* @throws ScopeNotCreatedException if scope doesn't exist
102
*/
103
fun Koin.getScope(scopeId: ScopeID): Scope
104
105
/**
106
* Get an existing scope by ID or null if not found
107
* @param scopeId - Scope identifier
108
* @return Existing scope or null
109
*/
110
fun Koin.getScopeOrNull(scopeId: ScopeID): Scope?
111
112
/**
113
* Delete a scope and close all its instances
114
* @param scopeId - Scope identifier to delete
115
*/
116
fun Koin.deleteScope(scopeId: ScopeID)
117
```
118
119
**Usage Examples:**
120
121
```kotlin
122
// Get or create scope
123
val scope = koin.getOrCreateScope("session-123", named("user-session"))
124
125
// Get existing scope safely
126
val existingScope = koin.getScopeOrNull("session-123")
127
if (existingScope != null) {
128
val userService = existingScope.get<UserService>()
129
}
130
131
// Get existing scope (throws if not found)
132
try {
133
val scope = koin.getScope("session-123")
134
// Use scope...
135
} catch (e: ScopeNotCreatedException) {
136
println("Scope not found")
137
}
138
139
// Clean up scope when done
140
koin.deleteScope("session-123")
141
```
142
143
### Scope Class
144
145
Container for scoped dependency injection with lifecycle management.
146
147
```kotlin { .api }
148
class Scope {
149
/** Qualifier identifying the scope type */
150
val scopeQualifier: Qualifier
151
152
/** Unique identifier for this scope instance */
153
val id: ScopeID
154
155
/** Whether this is the root scope */
156
val isRoot: Boolean
157
158
/** Optional scope archetype for additional typing */
159
val scopeArchetype: TypeQualifier?
160
161
/** Whether this scope has been closed */
162
val closed: Boolean
163
164
/**
165
* Get a dependency from this scope
166
* @param qualifier - Optional qualifier
167
* @param parameters - Optional parameters
168
* @return Instance from this scope or parent scopes
169
*/
170
inline fun <reified T : Any> get(qualifier: Qualifier? = null, noinline parameters: ParametersDefinition? = null): T
171
172
/**
173
* Get a dependency from this scope or null if not found
174
* @param qualifier - Optional qualifier
175
* @param parameters - Optional parameters
176
* @return Instance from this scope or null
177
*/
178
inline fun <reified T : Any> getOrNull(qualifier: Qualifier? = null, noinline parameters: ParametersDefinition? = null): T?
179
180
/**
181
* Get a dependency by class from this scope
182
* @param clazz - Class type to resolve
183
* @param qualifier - Optional qualifier
184
* @param parameters - Optional parameters
185
* @return Instance from this scope
186
*/
187
fun <T> get(clazz: KClass<*>, qualifier: Qualifier? = null, parameters: ParametersDefinition? = null): T
188
189
/**
190
* Get a dependency by class from this scope or null if not found
191
* @param clazz - Class type to resolve
192
* @param qualifier - Optional qualifier
193
* @param parameters - Optional parameters
194
* @return Instance from this scope or null
195
*/
196
fun <T> getOrNull(clazz: KClass<*>, qualifier: Qualifier? = null, parameters: ParametersDefinition? = null): T?
197
198
/**
199
* Get lazy dependency from this scope
200
* @param qualifier - Optional qualifier
201
* @param mode - Thread safety mode
202
* @param parameters - Optional parameters
203
* @return Lazy delegate for the dependency
204
*/
205
inline fun <reified T : Any> inject(qualifier: Qualifier? = null, mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED, noinline parameters: ParametersDefinition? = null): Lazy<T>
206
207
/**
208
* Get lazy optional dependency from this scope
209
* @param qualifier - Optional qualifier
210
* @param mode - Thread safety mode
211
* @param parameters - Optional parameters
212
* @return Lazy delegate for the optional dependency
213
*/
214
inline fun <reified T : Any> injectOrNull(qualifier: Qualifier? = null, mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED, noinline parameters: ParametersDefinition? = null): Lazy<T?>
215
216
/**
217
* Get the source object associated with this scope
218
* @return Source object or null
219
*/
220
inline fun <reified T : Any> getSource(): T?
221
222
/**
223
* Get all instances of a type from this scope
224
* @return List of all instances of the given type
225
*/
226
inline fun <reified T : Any> getAll(): List<T>
227
228
/**
229
* Get all instances of a class from this scope
230
* @param clazz - Class type to resolve
231
* @return List of all instances of the given class
232
*/
233
fun <T> getAll(clazz: KClass<*>): List<T>
234
235
/**
236
* Link this scope to other scopes for dependency resolution
237
* @param scopes - Scopes to link to
238
*/
239
fun linkTo(vararg scopes: Scope)
240
241
/**
242
* Unlink this scope from other scopes
243
* @param scopes - Scopes to unlink from
244
*/
245
fun unlink(vararg scopes: Scope)
246
247
/**
248
* Declare an instance in this scope at runtime
249
* @param instance - Instance to declare
250
* @param qualifier - Optional qualifier
251
* @param secondaryTypes - Additional types this instance can be resolved as
252
* @param allowOverride - Whether to allow overriding existing definitions
253
* @param holdInstance - Whether to hold reference to the instance
254
*/
255
inline fun <reified T> declare(instance: T, qualifier: Qualifier? = null, secondaryTypes: List<KClass<*>> = emptyList(), allowOverride: Boolean = true, holdInstance: Boolean = false)
256
257
/**
258
* Register a callback for scope lifecycle events
259
* @param callback - Callback to register
260
*/
261
fun registerCallback(callback: ScopeCallback)
262
263
/**
264
* Close this scope and cleanup all instances
265
*/
266
fun close()
267
268
/**
269
* Get the parent Koin container
270
* @return Parent Koin instance
271
*/
272
fun getKoin(): Koin
273
274
/**
275
* Get a child scope by ID
276
* @param scopeID - Child scope identifier
277
* @return Child scope instance
278
*/
279
fun getScope(scopeID: ScopeID): Scope
280
281
/**
282
* Get a property with default value from this scope
283
* @param key - Property key
284
* @param defaultValue - Default value if not found
285
* @return Property value or default
286
*/
287
fun <T : Any> getProperty(key: String, defaultValue: T): T
288
289
/**
290
* Get an optional property from this scope
291
* @param key - Property key
292
* @return Property value or null
293
*/
294
fun <T : Any> getPropertyOrNull(key: String): T?
295
296
/**
297
* Get a property from this scope
298
* @param key - Property key
299
* @return Property value
300
*/
301
fun <T : Any> getProperty(key: String): T
302
}
303
```
304
305
**Usage Examples:**
306
307
```kotlin
308
import org.koin.core.scope.Scope
309
import org.koin.core.parameter.parametersOf
310
311
class WebRequestHandler {
312
fun handleRequest(requestId: String, userId: String) {
313
// Create request scope
314
val requestScope = koin.createScope<RequestScope>(requestId)
315
316
try {
317
// Declare request-specific instances
318
requestScope.declare(RequestId(requestId))
319
requestScope.declare(UserId(userId))
320
321
// Get scoped dependencies
322
val requestContext = requestScope.get<RequestContext>()
323
val userSession = requestScope.get<UserSession>()
324
val processor = requestScope.get<RequestProcessor>()
325
326
// Use lazy injection within scope
327
val logger: RequestLogger by requestScope.inject()
328
329
// Process request
330
processor.handle(requestContext)
331
logger.logCompletion()
332
333
} finally {
334
// Always close scope to cleanup resources
335
requestScope.close()
336
}
337
}
338
}
339
```
340
341
### Scope Linking
342
343
Link scopes together for hierarchical dependency resolution.
344
345
```kotlin { .api }
346
/**
347
* Link this scope to other scopes for dependency resolution fallback
348
* @param scopes - Variable number of scopes to link to
349
*/
350
fun Scope.linkTo(vararg scopes: Scope)
351
352
/**
353
* Unlink this scope from other scopes
354
* @param scopes - Variable number of scopes to unlink from
355
*/
356
fun Scope.unlink(vararg scopes: Scope)
357
```
358
359
**Usage Examples:**
360
361
```kotlin
362
// Create parent and child scopes
363
val applicationScope = koin.createScope<ApplicationScope>("app")
364
val userSessionScope = koin.createScope<UserSessionScope>("session-123")
365
val requestScope = koin.createScope<RequestScope>("request-456")
366
367
// Link scopes in hierarchy
368
requestScope.linkTo(userSessionScope, applicationScope)
369
userSessionScope.linkTo(applicationScope)
370
371
// Dependencies will be resolved from child -> parent
372
// 1. First check requestScope
373
// 2. Then check userSessionScope
374
// 3. Finally check applicationScope
375
val service = requestScope.get<SomeService>() // Resolved from any linked scope
376
377
// Unlink when scope relationships change
378
requestScope.unlink(userSessionScope)
379
```
380
381
### Scope Callbacks
382
383
Register callbacks for scope lifecycle events.
384
385
```kotlin { .api }
386
/**
387
* Interface for scope lifecycle callbacks
388
*/
389
interface ScopeCallback {
390
/** Called when scope is created */
391
fun onScopeCreated(qualifier: Qualifier, scope: Scope)
392
393
/** Called when scope is closed */
394
fun onScopeClosed(qualifier: Qualifier, scope: Scope)
395
}
396
397
/**
398
* Register a callback for scope lifecycle events
399
* @param callback - Callback to register
400
*/
401
fun Scope.registerCallback(callback: ScopeCallback)
402
```
403
404
**Usage Examples:**
405
406
```kotlin
407
class LoggingScopeCallback : ScopeCallback {
408
override fun onScopeCreated(qualifier: Qualifier, scope: Scope) {
409
println("Scope created: ${qualifier.value} - ${scope.id}")
410
}
411
412
override fun onScopeClosed(qualifier: Qualifier, scope: Scope) {
413
println("Scope closed: ${qualifier.value} - ${scope.id}")
414
}
415
}
416
417
// Register callback
418
val scope = koin.createScope<RequestScope>("request-123")
419
scope.registerCallback(LoggingScopeCallback())
420
421
// Callbacks will be invoked during scope lifecycle
422
scope.close() // Triggers onScopeClosed
423
```
424
425
## Type Definitions
426
427
```kotlin { .api }
428
/**
429
* Type alias for scope identifiers
430
*/
431
typealias ScopeID = String
432
433
/**
434
* Interface for scope lifecycle callbacks
435
*/
436
interface ScopeCallback {
437
fun onScopeCreated(qualifier: Qualifier, scope: Scope)
438
fun onScopeClosed(qualifier: Qualifier, scope: Scope)
439
}
440
441
/**
442
* Exception thrown when scope is not found
443
*/
444
class ScopeNotCreatedException(scopeId: ScopeID) : RuntimeException("Scope '$scopeId' not created")
445
446
/**
447
* Exception thrown when scope is already created
448
*/
449
class ScopeAlreadyCreatedException(scopeId: ScopeID) : RuntimeException("Scope '$scopeId' already created")
450
451
/**
452
* Exception thrown when trying to use a closed scope
453
*/
454
class ClosedScopeException(scopeId: ScopeID) : RuntimeException("Scope '$scopeId' is closed")
455
```