0
# Scope Management
1
2
Hierarchical scope system for controlling dependency lifecycles and providing isolated dependency contexts for specific application areas. Scopes enable fine-grained resource management and dependency isolation.
3
4
## Capabilities
5
6
### Scope Class
7
8
Core scope implementation providing isolated dependency container functionality.
9
10
```kotlin { .api }
11
/**
12
* Scoped dependency container with lifecycle management
13
* @param scopeQualifier - Qualifier identifying the scope type
14
* @param id - Unique identifier for this scope instance
15
* @param isRoot - Whether this is a root scope
16
* @param _koin - Associated Koin instance
17
*/
18
class Scope(
19
val scopeQualifier: Qualifier,
20
val id: ScopeID,
21
val isRoot: Boolean = false,
22
private val _koin: Koin
23
) {
24
/**
25
* Whether this scope has been closed
26
*/
27
val closed: Boolean
28
29
/**
30
* Get associated Koin instance
31
* @return Koin instance
32
*/
33
fun getKoin(): Koin
34
35
/**
36
* Close scope and clean up resources
37
*/
38
fun close()
39
}
40
41
typealias ScopeID = String
42
```
43
44
### Scoped Dependency Injection
45
46
Inject dependencies from within a specific scope context.
47
48
```kotlin { .api }
49
/**
50
* Lazy inject dependency from scope
51
* @param qualifier - Optional qualifier to distinguish instances
52
* @param mode - Thread safety mode for lazy initialization
53
* @param parameters - Optional parameters for dependency creation
54
* @return Lazy delegate for the dependency
55
*/
56
inline fun <reified T> Scope.inject(
57
qualifier: Qualifier? = null,
58
mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED,
59
noinline parameters: ParametersDefinition? = null
60
): Lazy<T>
61
62
/**
63
* Lazy inject dependency from scope with nullable result
64
* @param qualifier - Optional qualifier to distinguish instances
65
* @param mode - Thread safety mode for lazy initialization
66
* @param parameters - Optional parameters for dependency creation
67
* @return Lazy delegate for nullable dependency
68
*/
69
inline fun <reified T> Scope.injectOrNull(
70
qualifier: Qualifier? = null,
71
mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED,
72
noinline parameters: ParametersDefinition? = null
73
): Lazy<T?>
74
75
/**
76
* Get dependency directly from scope
77
* @param qualifier - Optional qualifier to distinguish instances
78
* @param parameters - Optional parameters for dependency creation
79
* @return Resolved dependency instance
80
*/
81
inline fun <reified T> Scope.get(
82
qualifier: Qualifier? = null,
83
noinline parameters: ParametersDefinition? = null
84
): T
85
86
/**
87
* Get dependency from scope with nullable result
88
* @param qualifier - Optional qualifier to distinguish instances
89
* @param parameters - Optional parameters for dependency creation
90
* @return Resolved dependency instance or null
91
*/
92
inline fun <reified T> Scope.getOrNull(
93
qualifier: Qualifier? = null,
94
noinline parameters: ParametersDefinition? = null
95
): T?
96
97
/**
98
* Get all instances of a type from scope
99
* @return List of resolved instances
100
*/
101
inline fun <reified T> Scope.getAll(): List<T>
102
```
103
104
**Usage Examples:**
105
106
```kotlin
107
import org.koin.core.scope.Scope
108
import org.koin.core.qualifier.named
109
110
class UserFeature {
111
private val userScope: Scope = koin.createScope("user-123", named<UserScope>())
112
113
fun processUserData() {
114
// Lazy injection from scope
115
val userSession: UserSession by userScope.inject()
116
val userPrefs: UserPreferences by userScope.inject()
117
118
// Direct retrieval from scope
119
val userValidator = userScope.get<UserValidator>()
120
val userCache = userScope.get<UserCache>(named("memory"))
121
122
// Nullable retrieval
123
val optionalFeature = userScope.getOrNull<OptionalFeature>()
124
125
// Get all validators in scope
126
val allValidators = userScope.getAll<Validator>()
127
128
// Process with scoped dependencies
129
if (userValidator.isValid(userSession.userId)) {
130
val data = userPrefs.getData()
131
// Process data...
132
}
133
134
// Clean up scope when done
135
userScope.close()
136
}
137
}
138
```
139
140
### Scope Creation & Management
141
142
Create and manage scopes through the Koin container.
143
144
```kotlin { .api }
145
/**
146
* Create new scope in Koin container
147
* @param scopeId - Unique identifier for the scope
148
* @param qualifier - Scope type qualifier
149
* @param source - Optional source object for linking
150
* @return New scope instance
151
*/
152
fun Koin.createScope(
153
scopeId: String,
154
qualifier: Qualifier,
155
source: Any? = null
156
): Scope
157
158
/**
159
* Get existing scope by ID
160
* @param scopeId - Scope identifier
161
* @return Existing scope instance
162
* @throws ScopeNotCreatedException if scope doesn't exist
163
*/
164
fun Koin.getScope(scopeId: String): Scope
165
166
/**
167
* Get existing scope or null
168
* @param scopeId - Scope identifier
169
* @return Existing scope or null
170
*/
171
fun Koin.getScopeOrNull(scopeId: String): Scope?
172
173
/**
174
* Delete scope by ID
175
* @param scopeId - Scope identifier
176
*/
177
fun Koin.deleteScope(scopeId: String)
178
179
/**
180
* Get or create scope
181
* @param scopeId - Scope identifier
182
* @param qualifier - Scope type qualifier
183
* @return Existing or new scope instance
184
*/
185
fun Koin.getOrCreateScope(scopeId: String, qualifier: Qualifier): Scope
186
```
187
188
**Usage Examples:**
189
190
```kotlin
191
import org.koin.core.context.GlobalContext
192
import org.koin.core.qualifier.named
193
194
class ScopeManager {
195
private val koin = GlobalContext.get()
196
197
fun createUserScope(userId: String): Scope {
198
return koin.createScope(
199
scopeId = "user-$userId",
200
qualifier = named<UserScope>()
201
)
202
}
203
204
fun getUserScope(userId: String): Scope? {
205
return koin.getScopeOrNull("user-$userId")
206
}
207
208
fun cleanupUserScope(userId: String) {
209
koin.deleteScope("user-$userId")
210
}
211
212
fun processUser(userId: String) {
213
// Get or create scope
214
val scope = koin.getOrCreateScope("user-$userId", named<UserScope>())
215
216
// Use scope
217
val userService = scope.get<UserService>()
218
userService.processUser(userId)
219
220
// Scope remains active for future use
221
}
222
}
223
```
224
225
### Scope Linking & Source Association
226
227
Link scopes together and associate scopes with source objects for automatic cleanup.
228
229
```kotlin { .api }
230
/**
231
* Link this scope to another scope
232
* @param scope - Target scope to link to
233
*/
234
fun Scope.linkTo(scope: Scope)
235
236
/**
237
* Unlink this scope from another scope
238
* @param scope - Target scope to unlink from
239
*/
240
fun Scope.unlink(scope: Scope)
241
242
/**
243
* Get source object associated with this scope
244
* @return Source object or null
245
*/
246
fun <T> Scope.getSource(): T?
247
248
/**
249
* Declare additional instance in scope
250
* @param instance - Instance to declare
251
* @param qualifier - Optional qualifier
252
* @param secondaryTypes - Additional types to bind
253
* @param allowOverride - Whether to allow overriding existing declaration
254
*/
255
inline fun <reified T> Scope.declare(
256
instance: T,
257
qualifier: Qualifier? = null,
258
secondaryTypes: List<KClass<*>>? = null,
259
allowOverride: Boolean = false
260
)
261
```
262
263
**Usage Examples:**
264
265
```kotlin
266
import org.koin.core.scope.Scope
267
import org.koin.core.qualifier.named
268
269
class ActivityScope(private val activity: Activity) {
270
private val activityScope: Scope = koin.createScope(
271
scopeId = "activity-${activity.hashCode()}",
272
qualifier = named<ActivityScope>(),
273
source = activity // Link scope to activity lifecycle
274
)
275
276
private val featureScope: Scope = koin.createScope(
277
scopeId = "feature-${activity.hashCode()}",
278
qualifier = named<FeatureScope>()
279
)
280
281
fun initialize() {
282
// Link feature scope to activity scope
283
featureScope.linkTo(activityScope)
284
285
// Declare runtime instance in scope
286
activityScope.declare(
287
instance = ActivityManager(activity),
288
qualifier = named("manager")
289
)
290
291
// Bind additional types
292
activityScope.declare(
293
instance = CustomLogger(),
294
secondaryTypes = listOf(Logger::class, Closeable::class)
295
)
296
}
297
298
fun getFeatureScope(): Scope = featureScope
299
300
fun cleanup() {
301
// Unlink scopes
302
featureScope.unlink(activityScope)
303
304
// Close scopes
305
featureScope.close()
306
activityScope.close()
307
308
// Get source for final cleanup
309
val sourceActivity = activityScope.getSource<Activity>()
310
sourceActivity?.finish()
311
}
312
}
313
```
314
315
### Scope Properties
316
317
Access properties from scope with fallback to parent scopes.
318
319
```kotlin { .api }
320
/**
321
* Get property value from scope
322
* @param key - Property key
323
* @param defaultValue - Default value if property not found
324
* @return Property value
325
*/
326
fun <T> Scope.getProperty(key: String, defaultValue: T): T
327
328
/**
329
* Get property value from scope
330
* @param key - Property key
331
* @return Property value or null
332
*/
333
fun <T> Scope.getProperty(key: String): T?
334
335
/**
336
* Set property value in underlying Koin instance
337
* @param key - Property key
338
* @param value - Property value
339
*/
340
fun Scope.setProperty(key: String, value: Any?)
341
```
342
343
**Usage Examples:**
344
345
```kotlin
346
import org.koin.core.scope.Scope
347
348
class ConfigurableScope(private val scope: Scope) {
349
350
fun configure() {
351
// Get configuration properties
352
val timeout = scope.getProperty("http.timeout", 30)
353
val baseUrl = scope.getProperty<String>("api.baseUrl")
354
val debug = scope.getProperty("debug.enabled", false)
355
356
// Set runtime properties
357
scope.setProperty("session.id", generateSessionId())
358
scope.setProperty("startup.time", System.currentTimeMillis())
359
360
// Use properties for configuration
361
val httpClient = scope.get<HttpClient> {
362
parametersOf(baseUrl, timeout)
363
}
364
365
if (debug) {
366
scope.get<Logger>().info("Debug mode enabled")
367
}
368
}
369
}
370
```
371
372
## Scope Lifecycle Patterns
373
374
### Request Scope Pattern
375
376
```kotlin
377
import org.koin.core.qualifier.named
378
379
// Define request scope
380
val requestScope = named<RequestScope>()
381
382
// Module with request-scoped dependencies
383
val requestModule = module {
384
scope(requestScope) {
385
scoped<RequestContext> { RequestContextImpl() }
386
scoped<UserSession> { UserSessionImpl(get()) }
387
factory<RequestHandler> { RequestHandlerImpl(get(), get()) }
388
}
389
}
390
391
// Usage in web controller
392
class WebController : KoinComponent {
393
fun handleRequest(request: HttpRequest): HttpResponse {
394
val scope = getKoin().createScope(
395
scopeId = request.id,
396
qualifier = requestScope
397
)
398
399
try {
400
val handler = scope.get<RequestHandler>()
401
return handler.process(request)
402
} finally {
403
scope.close() // Clean up request resources
404
}
405
}
406
}
407
```
408
409
### Feature Module Scoping
410
411
```kotlin
412
import org.koin.core.qualifier.named
413
414
class FeatureModule {
415
private val featureScope = named<FeatureScope>()
416
417
val module = module {
418
// Global dependencies
419
single<Logger> { LoggerImpl() }
420
421
// Feature-scoped dependencies
422
scope(featureScope) {
423
scoped<FeatureConfig> { FeatureConfigImpl(get()) }
424
scoped<FeatureService> { FeatureServiceImpl(get(), get()) }
425
factory<FeatureProcessor> { FeatureProcessorImpl(get()) }
426
}
427
}
428
429
fun createFeatureScope(featureId: String): Scope {
430
return GlobalContext.get().createScope(
431
scopeId = "feature-$featureId",
432
qualifier = featureScope
433
)
434
}
435
}
436
```
437
438
## Types
439
440
```kotlin { .api }
441
typealias ScopeID = String
442
443
data class ScopeDefinition(
444
val qualifier: Qualifier,
445
val definition: Definition<*>,
446
val secondaryTypes: List<KClass<*>>,
447
val isCreatedAtStart: Boolean
448
)
449
450
class ScopeRegistry {
451
fun saveDefinition(scopeQualifier: Qualifier, definition: ScopeDefinition)
452
fun getScopeDefinition(scopeQualifier: Qualifier): ScopeDefinition?
453
}
454
455
// Scope-related exceptions
456
class ScopeNotCreatedException(message: String) : RuntimeException(message)
457
class ScopeAlreadyCreatedException(message: String) : RuntimeException(message)
458
class ClosedScopeException(message: String) : RuntimeException(message)
459
```