or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdcomponents.mdindex.mdmodule-dsl.mdscopes.md

scopes.mddocs/

0

# Scoped Dependencies

1

2

Koin scopes provide lifecycle-aware dependency management, allowing you to create and manage dependencies that are tied to specific lifecycles like user sessions, request contexts, or feature workflows.

3

4

## Scope Basics

5

6

```kotlin { .api }

7

class Scope(

8

val scopeQualifier: Qualifier,

9

val id: ScopeID,

10

val isRoot: Boolean = false,

11

val _koin: Koin

12

) {

13

inline fun <reified T> get(

14

qualifier: Qualifier? = null,

15

noinline parameters: ParametersDefinition? = null

16

): T

17

18

inline fun <reified T> inject(

19

qualifier: Qualifier? = null,

20

mode: LazyThreadSafetyMode = KoinPlatformTools.defaultLazyMode(),

21

noinline parameters: ParametersDefinition? = null

22

): Lazy<T>

23

24

fun close()

25

}

26

27

typealias ScopeID = String

28

```

29

30

Scopes are containers for dependencies that share a common lifecycle. When a scope is closed, all its scoped instances are released.

31

32

## Defining Scoped Dependencies

33

34

### In Modules

35

36

```kotlin { .api }

37

fun Module.scope(qualifier: Qualifier, scopeSet: ScopeDSL.() -> Unit)

38

inline fun <reified T> Module.scope(scopeSet: ScopeDSL.() -> Unit)

39

40

class ScopeDSL(val scopeQualifier: Qualifier, val module: Module) {

41

inline fun <reified T> scoped(

42

qualifier: Qualifier? = null,

43

noinline definition: Definition<T>

44

): KoinDefinition<T>

45

46

inline fun <reified T> factory(

47

qualifier: Qualifier? = null,

48

noinline definition: Definition<T>

49

): KoinDefinition<T>

50

}

51

```

52

53

### Usage Examples

54

55

```kotlin

56

val userModule = module {

57

// Type-based scope

58

scope<UserSession> {

59

scoped<SessionData> { SessionDataImpl() }

60

scoped<UserPreferences> { UserPreferencesImpl(get()) }

61

scoped<ShoppingCart> { ShoppingCartImpl(get()) }

62

}

63

64

// Named scope

65

scope(named("request")) {

66

scoped<RequestContext> { RequestContextImpl() }

67

scoped<ValidationService> { ValidationServiceImpl(get()) }

68

}

69

}

70

```

71

72

## Creating and Managing Scopes

73

74

### Manual Scope Creation

75

76

```kotlin { .api }

77

fun Koin.createScope(scopeId: ScopeID, qualifier: Qualifier, source: Any? = null): Scope

78

fun Koin.getOrCreateScope(scopeId: ScopeID, qualifier: Qualifier, source: Any? = null): Scope

79

fun Koin.getScope(scopeId: ScopeID): Scope

80

fun Koin.getScopeOrNull(scopeId: ScopeID): Scope?

81

```

82

83

### Example Usage

84

85

```kotlin

86

class RequestHandler : KoinComponent {

87

fun handleRequest(requestId: String) {

88

// Create a request scope

89

val requestScope = getKoin().createScope(

90

scopeId = "request-$requestId",

91

qualifier = named("request")

92

)

93

94

try {

95

// Use scoped dependencies

96

val context = requestScope.get<RequestContext>()

97

val validator = requestScope.get<ValidationService>()

98

99

// Process request...

100

101

} finally {

102

// Always close scope to clean up

103

requestScope.close()

104

}

105

}

106

}

107

```

108

109

## KoinScopeComponent Integration

110

111

```kotlin { .api }

112

interface KoinScopeComponent : KoinComponent {

113

val scope: Scope

114

}

115

```

116

117

### Component Extension Functions

118

119

```kotlin { .api }

120

fun <T : Any> T.getScopeId(): ScopeID

121

fun <T : Any> T.getScopeName(): TypeQualifier

122

123

fun <T : KoinScopeComponent> T.createScope(

124

scopeId: ScopeID = getScopeId(),

125

source: Any? = null,

126

scopeArchetype: TypeQualifier? = null

127

): Scope

128

129

fun <T : KoinScopeComponent> T.getScopeOrNull(): Scope?

130

```

131

132

### Automatic Scope Management

133

134

```kotlin

135

class UserSession : KoinScopeComponent {

136

override val scope: Scope = createScope()

137

138

// These will be resolved from the session scope

139

private val sessionData: SessionData by scope.inject()

140

private val preferences: UserPreferences by scope.inject()

141

private val cart: ShoppingCart by scope.inject()

142

143

fun login(userId: String) {

144

sessionData.userId = userId

145

preferences.load(userId)

146

}

147

148

fun logout() {

149

scope.close() // Cleans up all scoped instances

150

}

151

}

152

153

class ShoppingFeature : KoinScopeComponent {

154

override val scope: Scope = createScope()

155

156

private val cart: ShoppingCart by scope.inject()

157

private val paymentService: PaymentService by scope.inject()

158

159

fun addToCart(item: Item) {

160

cart.add(item)

161

}

162

163

fun checkout() {

164

val items = cart.getItems()

165

paymentService.processPayment(items)

166

}

167

168

fun cleanup() {

169

scope.close()

170

}

171

}

172

```

173

174

## Scope Lifecycle Patterns

175

176

### Request Scope Pattern

177

178

```kotlin

179

val webModule = module {

180

scope(named("request")) {

181

scoped<RequestContext> { RequestContextImpl() }

182

scoped<UserSession> { UserSessionImpl(get()) }

183

scoped<DatabaseTransaction> { DatabaseTransactionImpl() }

184

}

185

}

186

187

class RequestProcessor : KoinComponent {

188

fun processRequest(request: HttpRequest): HttpResponse {

189

val scope = getKoin().createScope("req-${request.id}", named("request"))

190

191

return try {

192

val context = scope.get<RequestContext>()

193

val transaction = scope.get<DatabaseTransaction>()

194

195

// Process with scoped dependencies

196

handleRequest(request, context, transaction)

197

198

} finally {

199

scope.close()

200

}

201

}

202

}

203

```

204

205

### Feature Scope Pattern

206

207

```kotlin

208

val featureModule = module {

209

scope<OrderWorkflow> {

210

scoped<OrderBuilder> { OrderBuilderImpl() }

211

scoped<InventoryChecker> { InventoryCheckerImpl(get()) }

212

scoped<PaymentProcessor> { PaymentProcessorImpl(get()) }

213

}

214

}

215

216

class OrderWorkflow : KoinScopeComponent {

217

override val scope: Scope = createScope()

218

219

private val orderBuilder: OrderBuilder by scope.inject()

220

private val inventoryChecker: InventoryChecker by scope.inject()

221

private val paymentProcessor: PaymentProcessor by scope.inject()

222

223

suspend fun processOrder(orderData: OrderData): OrderResult {

224

val order = orderBuilder.build(orderData)

225

val available = inventoryChecker.check(order.items)

226

227

return if (available) {

228

paymentProcessor.process(order)

229

} else {

230

OrderResult.OutOfStock

231

}

232

}

233

234

fun complete() {

235

scope.close()

236

}

237

}

238

```

239

240

## Scope Linking and Hierarchy

241

242

### Parent-Child Scopes

243

244

```kotlin

245

class ParentScope : KoinScopeComponent {

246

override val scope: Scope = createScope()

247

248

fun createChildScope(): Scope {

249

return getKoin().createScope(

250

scopeId = "child-${System.currentTimeMillis()}",

251

qualifier = named("child"),

252

source = this

253

)

254

}

255

}

256

```

257

258

### Scope Dependencies

259

260

```kotlin

261

val hierarchicalModule = module {

262

scope(named("parent")) {

263

scoped<ParentService> { ParentServiceImpl() }

264

}

265

266

scope(named("child")) {

267

scoped<ChildService> {

268

// Can access parent scope dependencies

269

ChildServiceImpl(get<ParentService>())

270

}

271

}

272

}

273

```

274

275

## Error Handling

276

277

```kotlin { .api }

278

class ScopeNotCreatedException(message: String) : RuntimeException(message)

279

class ClosedScopeException(message: String) : RuntimeException(message)

280

```

281

282

### Safe Scope Operations

283

284

```kotlin

285

class SafeScopeHandler : KoinComponent {

286

fun safeGetFromScope(scopeId: ScopeID): UserService? {

287

return try {

288

val scope = getKoin().getScope(scopeId)

289

scope.get<UserService>()

290

} catch (e: ScopeNotCreatedException) {

291

null

292

} catch (e: ClosedScopeException) {

293

null

294

}

295

}

296

}

297

```

298

299

## Best Practices

300

301

### 1. Always Close Scopes

302

303

```kotlin

304

// Good - using try-finally

305

val scope = getKoin().createScope("temp", named("temp"))

306

try {

307

val service = scope.get<TempService>()

308

service.doWork()

309

} finally {

310

scope.close()

311

}

312

313

// Better - using use-like pattern

314

inline fun <T> withScope(

315

scopeId: ScopeID,

316

qualifier: Qualifier,

317

block: (Scope) -> T

318

): T {

319

val scope = getKoin().createScope(scopeId, qualifier)

320

return try {

321

block(scope)

322

} finally {

323

scope.close()

324

}

325

}

326

```

327

328

### 2. Scope Naming

329

330

```kotlin

331

// Use descriptive scope IDs

332

val userScope = createScope("user-${userId}", named("user"))

333

val requestScope = createScope("request-${requestId}", named("request"))

334

val featureScope = createScope("feature-shopping-${sessionId}", named("shopping"))

335

```

336

337

### 3. Lifecycle Alignment

338

339

```kotlin

340

class ActivityController : KoinScopeComponent {

341

override val scope: Scope = createScope()

342

343

fun onCreate() {

344

// Scope is created, scoped dependencies available

345

}

346

347

fun onDestroy() {

348

scope.close() // Clean up when lifecycle ends

349

}

350

}

351

```