or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-startup.mdcontext-management.mddependency-injection.mderror-handling.mdindex.mdlogging-system.mdmodule-system.mdqualifiers-parameters.mdscoping-lifecycle.md

scoping-lifecycle.mddocs/

0

# Scoping and Lifecycle Management

1

2

Scoped dependency management for controlling instance lifecycle and cleanup within defined boundaries like sessions, requests, or custom application scopes.

3

4

## Capabilities

5

6

### Scope Management

7

8

Create and manage scoped containers for lifecycle-bound dependencies.

9

10

```javascript { .api }

11

class Scope {

12

/**

13

* Get scoped instance from scope

14

* @param qualifier - Optional qualifier for specific instance

15

* @param parameters - Optional parameters for instance creation

16

* @returns Instance of type T from scope

17

* @throws ClosedScopeException if scope is closed

18

*/

19

get<T>(qualifier?: Qualifier, parameters?: () => ParametersHolder): T;

20

21

/**

22

* Get scoped instance or null if not found

23

* @param qualifier - Optional qualifier for specific instance

24

* @param parameters - Optional parameters for instance creation

25

* @returns Instance of type T or null if not found

26

*/

27

getOrNull<T>(qualifier?: Qualifier, parameters?: () => ParametersHolder): T | null;

28

29

/**

30

* Lazy inject from scope - resolved on first access

31

* @param qualifier - Optional qualifier for specific instance

32

* @param mode - Thread safety mode for lazy initialization

33

* @param parameters - Optional parameters for instance creation

34

* @returns Lazy<T> wrapper that resolves from scope

35

*/

36

inject<T>(

37

qualifier?: Qualifier,

38

mode?: LazyThreadSafetyMode,

39

parameters?: () => ParametersHolder

40

): Lazy<T>;

41

42

/**

43

* Link to parent scopes for dependency resolution fallback

44

* @param scopes - Parent scopes to link to

45

*/

46

linkTo(...scopes: Scope[]): void;

47

48

/**

49

* Close scope and cleanup all scoped instances

50

* Calls onClose callbacks for all managed instances

51

*/

52

close(): void;

53

54

/**

55

* Check if scope is closed

56

* @returns true if scope is closed

57

*/

58

closed: boolean;

59

60

/**

61

* Scope identifier

62

*/

63

id: string;

64

65

/**

66

* Scope qualifier used for identification

67

*/

68

scopeQualifier: Qualifier;

69

}

70

```

71

72

**Usage Examples:**

73

74

```javascript

75

import { startKoin, module, named } from "koin-core";

76

77

// Define scoped module

78

const webModule = module((builder) => {

79

builder.scope(named("session"), (scopeBuilder) => {

80

scopeBuilder.scoped(() => new UserSession());

81

scopeBuilder.scoped(() => new ShoppingCart());

82

});

83

});

84

85

startKoin((app) => app.modules([webModule]));

86

87

// Create and use scope

88

const koin = GlobalContext.get();

89

const sessionScope = koin.createScope("user123", named("session"));

90

91

try {

92

// Get scoped instances

93

const userSession = sessionScope.get(); // UserSession

94

const cart = sessionScope.get(); // ShoppingCart

95

96

// Scoped instances persist within scope

97

const sameSession = sessionScope.get(); // Same UserSession instance

98

99

// Safe retrieval

100

const optionalService = sessionScope.getOrNull(); // Service | null

101

102

} finally {

103

// Always close scope to cleanup resources

104

sessionScope.close();

105

}

106

```

107

108

### Scope Creation and Management

109

110

Create, retrieve, and manage scopes within the Koin container.

111

112

```javascript { .api }

113

class Koin {

114

/**

115

* Create new scope with identifier and qualifier

116

* @param scopeId - Unique scope identifier

117

* @param qualifier - Scope qualifier defining scope type

118

* @param source - Optional source object for scope context

119

* @returns New Scope instance

120

* @throws ScopeAlreadyCreatedException if scope already exists

121

*/

122

createScope(scopeId: string, qualifier: Qualifier, source?: any): Scope;

123

124

/**

125

* Create typed scope with identifier and inferred qualifier

126

* @param scopeId - Unique scope identifier

127

* @param source - Optional source object for scope context

128

* @returns New Scope instance for type T

129

*/

130

createScope<T>(scopeId: string, source?: any): Scope;

131

132

/**

133

* Get existing scope by identifier

134

* @param scopeId - Scope identifier

135

* @returns Existing Scope instance

136

* @throws ScopeNotCreatedException if scope doesn't exist

137

*/

138

getScope(scopeId: string): Scope;

139

140

/**

141

* Get existing scope or null if not found

142

* @param scopeId - Scope identifier

143

* @returns Scope instance or null

144

*/

145

getScopeOrNull(scopeId: string): Scope | null;

146

147

/**

148

* Delete scope and cleanup resources

149

* @param scopeId - Scope identifier to delete

150

*/

151

deleteScope(scopeId: string): void;

152

153

/**

154

* Get all active scopes

155

* @returns Array of all active Scope instances

156

*/

157

getAllScopes(): Scope[];

158

}

159

```

160

161

**Usage Examples:**

162

163

```javascript

164

import { startKoin, module, named } from "koin-core";

165

166

const appModule = module((builder) => {

167

builder.scope(named("request"), (scopeBuilder) => {

168

scopeBuilder.scoped(() => new RequestContext());

169

scopeBuilder.scoped(() => new DatabaseTransaction());

170

});

171

172

builder.scope(named("session"), (scopeBuilder) => {

173

scopeBuilder.scoped(() => new UserSession());

174

});

175

});

176

177

startKoin((app) => app.modules([appModule]));

178

179

const koin = GlobalContext.get();

180

181

// Create scopes

182

const requestScope = koin.createScope("req-001", named("request"));

183

const sessionScope = koin.createScope("session-abc", named("session"), userObject);

184

185

// Retrieve existing scopes

186

const existingRequest = koin.getScope("req-001");

187

const maybeScope = koin.getScopeOrNull("non-existent"); // null

188

189

// Get all active scopes

190

const allScopes = koin.getAllScopes();

191

console.log(`Active scopes: ${allScopes.length}`);

192

193

// Cleanup

194

koin.deleteScope("req-001");

195

sessionScope.close(); // Alternative cleanup method

196

```

197

198

### Scoped Component Interface

199

200

Use KoinScopeComponent for classes that manage their own scope lifecycle.

201

202

```javascript { .api }

203

interface KoinScopeComponent extends KoinComponent {

204

/**

205

* Current scope instance for this component

206

*/

207

scope: Scope;

208

}

209

210

// Extension functions for KoinScopeComponent

211

/**

212

* Create scope for component with identifier

213

* @param scopeId - Scope identifier

214

* @param source - Optional source object

215

* @returns Created Scope instance

216

*/

217

function createScope(

218

this: KoinScopeComponent,

219

scopeId: string,

220

source?: any

221

): Scope;

222

223

/**

224

* Get component's scope or null if not created

225

* @returns Scope instance or null

226

*/

227

function getScopeOrNull(this: KoinScopeComponent): Scope | null;

228

229

/**

230

* Create lazy scope - scope created on first access

231

* @returns Lazy<Scope> wrapper

232

*/

233

function newScope(this: KoinScopeComponent): Lazy<Scope>;

234

235

/**

236

* Get existing scope or create new one

237

* @returns Scope instance

238

*/

239

function getOrCreateScope(this: KoinScopeComponent): Scope;

240

```

241

242

**Usage Examples:**

243

244

```javascript

245

import { KoinScopeComponent, named } from "koin-core";

246

247

class UserSessionController extends KoinScopeComponent {

248

constructor(userId) {

249

super();

250

this.userId = userId;

251

252

// Create scope for this component

253

this.scope = this.createScope(`session-${userId}`);

254

255

// Get scoped dependencies

256

this.userSession = this.scope.get(); // UserSession

257

this.preferences = this.scope.get(); // UserPreferences

258

}

259

260

async login() {

261

// Use scoped dependencies

262

await this.userSession.initialize();

263

await this.preferences.load();

264

}

265

266

async logout() {

267

// Cleanup scope on logout

268

this.scope.close();

269

}

270

}

271

272

class RequestHandler extends KoinScopeComponent {

273

constructor() {

274

super();

275

// Lazy scope creation - created when first accessed

276

this.lazyScope = this.newScope();

277

}

278

279

async handleRequest(request) {

280

// Scope created on first access

281

const scope = this.getOrCreateScope();

282

const requestContext = scope.get(); // RequestContext

283

284

try {

285

return await requestContext.process(request);

286

} finally {

287

// Cleanup after request

288

scope.close();

289

}

290

}

291

}

292

```

293

294

### Scope Linking and Hierarchies

295

296

Create parent-child relationships between scopes for hierarchical dependency resolution.

297

298

```javascript { .api }

299

class Scope {

300

/**

301

* Declare instance in scope for injection

302

* @param instance - Instance to declare

303

* @param qualifier - Optional qualifier for identification

304

* @param secondaryTypes - Additional types to bind

305

* @param allowOverride - Whether to allow overriding existing definition

306

* @param holdInstance - Whether scope should hold reference

307

* @returns BeanDefinition for the declared instance

308

*/

309

declare<T>(

310

instance: T,

311

qualifier?: Qualifier,

312

secondaryTypes?: any[],

313

allowOverride?: boolean,

314

holdInstance?: boolean

315

): BeanDefinition<T>;

316

317

/**

318

* Get property from scope context

319

* @param key - Property key

320

* @param defaultValue - Default value if not found

321

* @returns Property value

322

*/

323

getProperty<T>(key: string, defaultValue?: T): T;

324

325

/**

326

* Get property or null if not found

327

* @param key - Property key

328

* @returns Property value or null

329

*/

330

getPropertyOrNull<T>(key: string): T | null;

331

}

332

```

333

334

**Usage Examples:**

335

336

```javascript

337

import { startKoin, module, named } from "koin-core";

338

339

const hierarchicalModule = module((builder) => {

340

// Application-level scope

341

builder.scope(named("application"), (scopeBuilder) => {

342

scopeBuilder.scoped(() => new ConfigurationService());

343

scopeBuilder.scoped(() => new Logger());

344

});

345

346

// Session-level scope

347

builder.scope(named("session"), (scopeBuilder) => {

348

scopeBuilder.scoped(() => new UserSession());

349

scopeBuilder.scoped(() => new SecurityContext());

350

});

351

352

// Request-level scope

353

builder.scope(named("request"), (scopeBuilder) => {

354

scopeBuilder.scoped(() => new RequestContext());

355

scopeBuilder.factory(() => new RequestHandler());

356

});

357

});

358

359

startKoin((app) => app.modules([hierarchicalModule]));

360

361

const koin = GlobalContext.get();

362

363

// Create scope hierarchy

364

const appScope = koin.createScope("app", named("application"));

365

const sessionScope = koin.createScope("session-123", named("session"));

366

const requestScope = koin.createScope("req-456", named("request"));

367

368

// Link scopes for dependency resolution fallback

369

requestScope.linkTo(sessionScope, appScope);

370

sessionScope.linkTo(appScope);

371

372

// Request scope can resolve from session and app scopes

373

const requestHandler = requestScope.get(); // RequestHandler (from request scope)

374

const userSession = requestScope.get(); // UserSession (from session scope)

375

const config = requestScope.get(); // ConfigurationService (from app scope)

376

377

// Declare runtime instances in scope

378

const runtimeData = { timestamp: Date.now(), requestId: "req-456" };

379

requestScope.declare(runtimeData, named("request-data"));

380

381

// Access declared instance

382

const data = requestScope.get(named("request-data"));

383

384

// Cleanup hierarchy (child scopes first)

385

requestScope.close();

386

sessionScope.close();

387

appScope.close();

388

```

389

390

### Scope Callbacks and Lifecycle

391

392

Handle scope lifecycle events with callbacks for resource management.

393

394

```javascript { .api }

395

interface ScopeCallback {

396

/**

397

* Called when scope is created

398

* @param scope - The created scope

399

*/

400

onScopeCreated(scope: Scope): void;

401

402

/**

403

* Called when scope is closed

404

* @param scope - The closed scope

405

*/

406

onScopeClosed(scope: Scope): void;

407

}

408

409

class Koin {

410

/**

411

* Register scope callback for lifecycle events

412

* @param callback - ScopeCallback implementation

413

*/

414

registerScopeCallback(callback: ScopeCallback): void;

415

416

/**

417

* Unregister scope callback

418

* @param callback - ScopeCallback to remove

419

*/

420

unregisterScopeCallback(callback: ScopeCallback): void;

421

}

422

```

423

424

**Usage Examples:**

425

426

```javascript

427

import { startKoin, GlobalContext } from "koin-core";

428

429

class ScopeMonitor {

430

onScopeCreated(scope) {

431

console.log(`Scope created: ${scope.id} (${scope.scopeQualifier.value})`);

432

}

433

434

onScopeClosed(scope) {

435

console.log(`Scope closed: ${scope.id} (${scope.scopeQualifier.value})`);

436

}

437

}

438

439

startKoin((app) => app.modules([webModule]));

440

441

const koin = GlobalContext.get();

442

const monitor = new ScopeMonitor();

443

444

// Register lifecycle monitoring

445

koin.registerScopeCallback(monitor);

446

447

// Scope operations will trigger callbacks

448

const scope = koin.createScope("test", named("session")); // Logs: "Scope created..."

449

scope.close(); // Logs: "Scope closed..."

450

451

// Cleanup monitoring

452

koin.unregisterScopeCallback(monitor);

453

```

454

455

## Types

456

457

```javascript { .api }

458

/** Scope identifier type */

459

type ScopeID = string;

460

461

/** Scope callback interface for lifecycle events */

462

interface ScopeCallback {

463

onScopeCreated(scope: Scope): void;

464

onScopeClosed(scope: Scope): void;

465

}

466

467

/** Exception thrown when scope is already created */

468

class ScopeAlreadyCreatedException extends Error {

469

constructor(scopeId: string);

470

}

471

472

/** Exception thrown when scope is not created */

473

class ScopeNotCreatedException extends Error {

474

constructor(scopeId: string);

475

}

476

477

/** Exception thrown when attempting to use closed scope */

478

class ClosedScopeException extends Error {

479

constructor(scopeId: string);

480

}

481

482

/** Exception thrown when scope value is missing */

483

class MissingScopeValueException extends Error {

484

constructor(message: string);

485

}

486

487

/** Exception thrown when scope definition is not found */

488

class NoScopeDefFoundException extends Error {

489

constructor(message: string);

490

}

491

```