0
# Context Access
1
2
Functions to retrieve current Koin application and scope contexts from anywhere in the Compose hierarchy, providing access to the underlying Koin framework for advanced use cases.
3
4
## Capabilities
5
6
### Get Koin Application
7
8
Retrieve the current Koin application instance from the Compose context for direct access to Koin APIs.
9
10
```kotlin { .api }
11
/**
12
* Retrieve the current Koin application instance from composition
13
* @return Koin instance
14
* @throws UnknownKoinContext if Koin context is not found
15
*/
16
@Composable
17
fun getKoin(): Koin
18
```
19
20
**Usage Examples:**
21
22
```kotlin
23
@Composable
24
fun AdvancedComponent() {
25
val koin = getKoin()
26
27
// Access Koin APIs directly
28
val hasDefinition = koin.getOrNull<UserService>() != null
29
val scopeIds = koin.scopeRegistry.getAllScopeIds()
30
31
// Create custom scopes
32
val customScope = koin.createScope("custom-scope", named("feature"))
33
34
// Access properties
35
val apiUrl = koin.getProperty<String>("api.url")
36
37
// Manual dependency resolution
38
val service = koin.get<ApiService>(qualifier = named("v2"))
39
}
40
```
41
42
### Get Current Scope
43
44
Retrieve the current Koin scope from the Compose context for scope-specific operations.
45
46
```kotlin { .api }
47
/**
48
* Retrieve the current Koin scope from composition
49
* @return Scope instance
50
* @throws UnknownKoinContext if Koin context is not found
51
*/
52
@Composable
53
fun currentKoinScope(): Scope
54
```
55
56
**Usage Examples:**
57
58
```kotlin
59
@Composable
60
fun ScopeAwareComponent() {
61
val currentScope = currentKoinScope()
62
63
// Get scope information
64
val scopeId = currentScope.id
65
val scopeQualifier = currentScope.scopeQualifier
66
67
// Resolve scoped dependencies manually
68
val scopedService = currentScope.get<ScopedService>()
69
70
// Check if definition exists in current scope
71
val hasService = currentScope.getOrNull<MyService>() != null
72
73
// Create linked scope
74
val linkedScope = currentScope.createScope(
75
scopeId = "linked-scope",
76
qualifier = named("linked")
77
)
78
}
79
```
80
81
## Advanced Use Cases
82
83
### Direct Koin API Access
84
85
Use `getKoin()` for advanced Koin framework features not directly exposed through Compose APIs:
86
87
```kotlin
88
@Composable
89
fun KoinIntrospection() {
90
val koin = getKoin()
91
92
// Module management
93
val modules = koin.loadModules(listOf(dynamicModule))
94
koin.unloadModules(listOf(obsoleteModule))
95
96
// Property access
97
val config = mapOf(
98
"debug" to koin.getProperty<Boolean>("debug", false),
99
"version" to koin.getProperty<String>("app.version", "unknown")
100
)
101
102
// Scope registry inspection
103
val allScopes = koin.scopeRegistry.getAllScopes()
104
val rootScope = koin.scopeRegistry.rootScope
105
106
// Bean registry inspection
107
val definitions = koin.instanceRegistry.instances.size
108
}
109
```
110
111
### Scope Hierarchy Navigation
112
113
Use `currentKoinScope()` to navigate and manipulate scope hierarchies:
114
115
```kotlin
116
@Composable
117
fun ScopeHierarchy() {
118
val scope = currentKoinScope()
119
120
// Navigate scope hierarchy
121
val rootScope = scope.koin.scopeRegistry.rootScope
122
val parentScope = scope.getSource()
123
124
// Scope lifecycle management
125
val isActive = !scope.closed
126
val scopeDefinition = scope._scopeDefinition
127
128
// Linked scope creation
129
val childScope = scope.createScope(
130
scopeId = "child-${UUID.randomUUID()}",
131
qualifier = named("child")
132
)
133
134
// Cleanup on disposal
135
DisposableEffect(scope) {
136
onDispose {
137
if (!childScope.closed) {
138
childScope.close()
139
}
140
}
141
}
142
}
143
```
144
145
## Integration with Compose State
146
147
### Reactive Koin Properties
148
149
Create reactive state from Koin properties:
150
151
```kotlin
152
@Composable
153
fun ReactiveConfig() {
154
val koin = getKoin()
155
156
// Convert Koin properties to Compose state
157
val debugMode by remember {
158
derivedStateOf { koin.getProperty<Boolean>("debug", false) }
159
}
160
161
val theme by remember {
162
derivedStateOf { koin.getProperty<String>("ui.theme", "light") }
163
}
164
165
// React to configuration changes
166
LaunchedEffect(debugMode) {
167
if (debugMode) {
168
println("Debug mode enabled")
169
}
170
}
171
}
172
```
173
174
### Scope-Based State Management
175
176
Use scopes for component-specific state management:
177
178
```kotlin
179
@Composable
180
fun ScopedState() {
181
val scope = currentKoinScope()
182
183
// Create scope-specific state
184
val scopedData by remember(scope) {
185
mutableStateOf(scope.get<InitialData>())
186
}
187
188
// Scope-specific effects
189
LaunchedEffect(scope) {
190
scope.get<ScopeListener>().onScopeCreated(scope.id)
191
}
192
193
DisposableEffect(scope) {
194
onDispose {
195
scope.get<ScopeListener>().onScopeDestroyed(scope.id)
196
}
197
}
198
}
199
```
200
201
## Error Handling
202
203
Both functions throw `UnknownKoinContext` when Koin context is not properly initialized:
204
205
```kotlin
206
@Composable
207
fun SafeContextAccess() {
208
try {
209
val koin = getKoin()
210
val scope = currentKoinScope()
211
212
// Use Koin and scope
213
NormalOperation(koin, scope)
214
215
} catch (e: UnknownKoinContext) {
216
// Handle missing Koin context
217
ErrorMessage("Koin context not initialized")
218
}
219
}
220
221
@Composable
222
fun ErrorMessage(message: String) {
223
Text(
224
text = message,
225
color = MaterialTheme.colors.error,
226
style = MaterialTheme.typography.body1
227
)
228
}
229
```
230
231
## Performance Considerations
232
233
### Caching Context Access
234
235
Cache Koin context access when used multiple times in the same composable:
236
237
```kotlin
238
@Composable
239
fun OptimizedContextAccess() {
240
val koin = remember { getKoin() }
241
val scope = remember { currentKoinScope() }
242
243
// Multiple operations with cached contexts
244
LaunchedEffect(koin, scope) {
245
val service1 = koin.get<Service1>()
246
val service2 = scope.get<Service2>()
247
val property = koin.getProperty<String>("config")
248
249
// Perform operations...
250
}
251
}
252
```
253
254
### Conditional Context Access
255
256
Access contexts only when needed to avoid unnecessary exceptions:
257
258
```kotlin
259
@Composable
260
fun ConditionalAccess(needsKoin: Boolean) {
261
if (needsKoin) {
262
val koin = getKoin()
263
val scope = currentKoinScope()
264
265
// Use contexts only when needed
266
KoinDependentContent(koin, scope)
267
} else {
268
StaticContent()
269
}
270
}
271
```
272
273
## Best Practices
274
275
1. **Cache Context Access**: Use `remember` to cache context access when used multiple times
276
2. **Handle Exceptions**: Always handle `UnknownKoinContext` appropriately
277
3. **Conditional Access**: Only access contexts when actually needed
278
4. **Scope Lifecycle**: Properly manage created scopes with `DisposableEffect`
279
5. **Direct API Usage**: Use context access for advanced scenarios not covered by injection APIs
280
6. **State Integration**: Leverage Compose state patterns with Koin contexts for reactive UIs