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

module-system.mddocs/

0

# Module System and Dependency Definitions

1

2

Module definition DSL for organizing and declaring dependencies with singletons, factories, scoped instances, and constructor-based definitions.

3

4

## Capabilities

5

6

### Module Creation

7

8

Define modules with dependency definitions using the fluent DSL.

9

10

```javascript { .api }

11

/**

12

* Define a module with dependency definitions

13

* @param createdAtStart - Whether to create instances immediately on startup (default: false)

14

* @param moduleDeclaration - Module configuration function

15

* @returns Module instance

16

*/

17

function module(

18

createdAtStart?: boolean,

19

moduleDeclaration: ModuleDeclaration

20

): Module;

21

22

/**

23

* Define a module with only the declaration function

24

* @param moduleDeclaration - Module configuration function

25

* @returns Module instance

26

*/

27

function module(moduleDeclaration: ModuleDeclaration): Module;

28

29

/**

30

* Create a Koin configuration

31

* @param declaration - Application configuration function

32

* @returns KoinConfiguration instance

33

*/

34

function koinConfiguration(declaration: KoinAppDeclaration): KoinConfiguration;

35

```

36

37

**Usage Examples:**

38

39

```javascript

40

import { module } from "koin-core";

41

42

// Basic module definition

43

const appModule = module((module) => {

44

module.single(null, false, () => new DatabaseService());

45

module.factory(null, () => new ApiClient());

46

});

47

48

// Module with eager creation

49

const eagerModule = module(true, (module) => {

50

module.single(null, true, () => new ConfigurationService());

51

});

52

```

53

54

### Dependency Definitions

55

56

Define different types of dependencies within modules.

57

58

```javascript { .api }

59

class Module {

60

/** Module unique identifier */

61

readonly id: string;

62

/** Whether module is loaded */

63

readonly isLoaded: boolean;

64

65

/**

66

* Define singleton instance - created once and reused

67

* @param qualifier - Optional qualifier for instance identification

68

* @param createdAtStart - Whether to create immediately (default: false)

69

* @param definition - Function that creates the instance

70

* @returns KoinDefinition for additional configuration

71

*/

72

single<T>(

73

qualifier?: Qualifier,

74

createdAtStart?: boolean,

75

definition: Definition<T>

76

): KoinDefinition<T>;

77

78

/**

79

* Define factory instance - new instance every request

80

* @param qualifier - Optional qualifier for instance identification

81

* @param definition - Function that creates the instance

82

* @returns KoinDefinition for additional configuration

83

*/

84

factory<T>(qualifier?: Qualifier, definition: Definition<T>): KoinDefinition<T>;

85

86

/**

87

* Define scoped instances within named scope

88

* @param qualifier - Scope qualifier

89

* @param scopeSet - Scope configuration function

90

*/

91

scope(qualifier: Qualifier, scopeSet: (scopeDSL: ScopeDSL) => void): void;

92

scope<T>(scopeSet: (scopeDSL: ScopeDSL) => void): void;

93

94

/**

95

* Include other modules

96

* @param modules - Modules to include

97

*/

98

includes(...modules: Module[]): void;

99

includes(modules: Module[]): void;

100

101

/**

102

* Module composition operators

103

*/

104

plus(module: Module): Module[];

105

plus(modules: Module[]): Module[];

106

}

107

```

108

109

**Usage Examples:**

110

111

```javascript

112

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

113

114

const appModule = module((module) => {

115

// Singleton - created once, reused

116

module.single(null, false, () => new DatabaseConnection("localhost:5432"));

117

118

// Qualified singleton

119

module.single(named("primary"), false, () => new DatabaseConnection("primary-db:5432"));

120

121

// Factory - new instance each time

122

module.factory(null, () => new HttpRequest());

123

124

// Qualified factory

125

module.factory(named("api"), () => new ApiClient("https://api.example.com"));

126

127

// Eager singleton - created at startup

128

module.single(null, true, () => new ConfigurationLoader());

129

});

130

```

131

132

### Constructor-Based Definitions

133

134

Enhanced DSL functions for constructor-based dependency definitions with automatic parameter resolution.

135

136

```javascript { .api }

137

/**

138

* Constructor-based singleton definition with 0 parameters

139

* @param constructor - Constructor function

140

* @returns BeanDefinition for additional configuration

141

*/

142

function singleOf<T>(constructor: () => T): BeanDefinition<T>;

143

144

/**

145

* Constructor-based singleton definition with 1 parameter

146

* @param constructor - Constructor function

147

* @returns BeanDefinition for additional configuration

148

*/

149

function singleOf<T, P1>(constructor: (p1: P1) => T): BeanDefinition<T>;

150

151

/**

152

* Constructor-based singleton definition with 2 parameters

153

* @param constructor - Constructor function

154

* @returns BeanDefinition for additional configuration

155

*/

156

function singleOf<T, P1, P2>(constructor: (p1: P1, p2: P2) => T): BeanDefinition<T>;

157

158

// Additional variants for up to 22 parameters...

159

160

/**

161

* Constructor-based factory definition with 0 parameters

162

* @param constructor - Constructor function

163

* @returns BeanDefinition for additional configuration

164

*/

165

function factoryOf<T>(constructor: () => T): BeanDefinition<T>;

166

167

/**

168

* Constructor-based factory definition with 1 parameter

169

* @param constructor - Constructor function

170

* @returns BeanDefinition for additional configuration

171

*/

172

function factoryOf<T, P1>(constructor: (p1: P1) => T): BeanDefinition<T>;

173

174

// Additional factoryOf variants for up to 22 parameters...

175

176

/**

177

* Constructor-based scoped definition with 0 parameters

178

* @param constructor - Constructor function

179

* @returns BeanDefinition for additional configuration

180

*/

181

function scopedOf<T>(constructor: () => T): BeanDefinition<T>;

182

183

/**

184

* Constructor-based scoped definition with 1 parameter

185

* @param constructor - Constructor function

186

* @returns BeanDefinition for additional configuration

187

*/

188

function scopedOf<T, P1>(constructor: (p1: P1) => T): BeanDefinition<T>;

189

190

// Additional scopedOf variants for up to 22 parameters...

191

```

192

193

**Usage Examples:**

194

195

```javascript

196

import { module, singleOf, factoryOf } from "koin-core";

197

198

class DatabaseService {

199

constructor(connectionString) {

200

this.connectionString = connectionString;

201

}

202

}

203

204

class ApiClient {

205

constructor(baseUrl, timeout) {

206

this.baseUrl = baseUrl;

207

this.timeout = timeout;

208

}

209

}

210

211

const appModule = module((builder) => {

212

// Constructor-based definitions automatically resolve parameters

213

builder.singleOf(DatabaseService); // Auto-resolves constructor parameters

214

builder.factoryOf(ApiClient); // Auto-resolves constructor parameters

215

216

// Dependencies for constructors

217

builder.single(() => "mongodb://localhost:27017"); // For DatabaseService

218

builder.single(() => "https://api.example.com"); // For ApiClient baseUrl

219

builder.single(() => 5000); // For ApiClient timeout

220

});

221

```

222

223

### Scope Definitions

224

225

Define scoped dependencies that live within specific lifecycle boundaries.

226

227

```javascript { .api }

228

class Module {

229

/**

230

* Define scoped instances within named scope

231

* @param qualifier - Scope identifier

232

* @param scopeSet - Scope configuration function

233

* @returns Module for chaining

234

*/

235

scope(qualifier: Qualifier, scopeSet: (builder: ScopeBuilder) => void): Module;

236

}

237

238

class ScopeBuilder {

239

/**

240

* Define scoped instance within scope

241

* @param definition - Function that creates the instance

242

* @returns BeanDefinition for additional configuration

243

*/

244

scoped<T>(definition: (scope: Scope, parameters: ParametersHolder) => T): BeanDefinition<T>;

245

246

/**

247

* Define qualified scoped instance

248

* @param qualifier - Qualifier for instance identification

249

* @param definition - Function that creates the instance

250

* @returns BeanDefinition for additional configuration

251

*/

252

scoped<T>(

253

qualifier: Qualifier,

254

definition: (scope: Scope, parameters: ParametersHolder) => T

255

): BeanDefinition<T>;

256

257

/**

258

* Define factory instance within scope

259

* @param definition - Function that creates the instance

260

* @returns BeanDefinition for additional configuration

261

*/

262

factory<T>(definition: (scope: Scope, parameters: ParametersHolder) => T): BeanDefinition<T>;

263

264

/**

265

* Define qualified factory instance within scope

266

* @param qualifier - Qualifier for instance identification

267

* @param definition - Function that creates the instance

268

* @returns BeanDefinition for additional configuration

269

*/

270

factory<T>(

271

qualifier: Qualifier,

272

definition: (scope: Scope, parameters: ParametersHolder) => T

273

): BeanDefinition<T>;

274

}

275

```

276

277

**Usage Examples:**

278

279

```javascript

280

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

281

282

const webModule = module((builder) => {

283

// Define a session scope

284

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

285

// User session - lives for duration of session scope

286

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

287

288

// Shopping cart - lives for duration of session scope

289

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

290

291

// HTTP request factory - new instance per request within session

292

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

293

});

294

295

// Define a request scope

296

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

297

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

298

scopeBuilder.scoped(named("api"), () => new ApiRequestHandler());

299

});

300

});

301

```

302

303

### Module Composition

304

305

Combine and organize modules for complex applications.

306

307

```javascript { .api }

308

class Module {

309

/**

310

* Include other modules in this module

311

* @param modules - Modules to include

312

* @returns Module for chaining

313

*/

314

includes(...modules: Module[]): Module;

315

316

/**

317

* Combine modules using plus operator

318

* @param module - Module to combine

319

* @returns New combined module

320

*/

321

plus(module: Module): Module;

322

323

/**

324

* Combine with multiple modules

325

* @param modules - Modules to combine

326

* @returns New combined module

327

*/

328

plus(modules: Module[]): Module;

329

}

330

```

331

332

**Usage Examples:**

333

334

```javascript

335

import { module } from "koin-core";

336

337

const coreModule = module((builder) => {

338

builder.single(() => new Logger());

339

builder.single(() => new ConfigService());

340

});

341

342

const databaseModule = module((builder) => {

343

builder.single(() => new DatabaseConnection());

344

builder.factory(() => new Repository());

345

});

346

347

const apiModule = module((builder) => {

348

builder.factory(() => new ApiClient());

349

builder.single(() => new AuthService());

350

});

351

352

// Combine modules using includes

353

const appModule = module((builder) => {

354

builder.includes(coreModule, databaseModule, apiModule);

355

builder.single(() => new AppService());

356

});

357

358

// Combine modules using plus operator

359

const combinedModule = coreModule.plus(databaseModule).plus(apiModule);

360

361

// Alternative combination syntax

362

const allModules = coreModule.plus([databaseModule, apiModule]);

363

```

364

365

### Bean Definition Configuration

366

367

Configure bean definitions with type binding and lifecycle callbacks.

368

369

```javascript { .api }

370

interface BeanDefinition<T> {

371

/**

372

* Bind additional compatible types for injection

373

* @param clazz - Class or interface to bind

374

* @returns BeanDefinition for chaining

375

*/

376

bind<S>(clazz: new (...args: any[]) => S): BeanDefinition<T>;

377

378

/**

379

* Bind additional compatible type using generics

380

* @returns BeanDefinition for chaining

381

*/

382

bind<S>(): BeanDefinition<T>;

383

384

/**

385

* Bind multiple compatible types

386

* @param classes - Array of classes to bind

387

* @returns BeanDefinition for chaining

388

*/

389

binds(classes: (new (...args: any[]) => any)[]): BeanDefinition<T>;

390

391

/**

392

* Add cleanup callback when instance is closed

393

* @param callback - Cleanup function

394

* @returns BeanDefinition for chaining

395

*/

396

onClose(callback: (instance: T) => void): BeanDefinition<T>;

397

}

398

```

399

400

**Usage Examples:**

401

402

```javascript

403

import { module } from "koin-core";

404

405

// Interfaces for binding

406

class DatabaseService {}

407

class IDataService {}

408

class ILoggable {}

409

410

const appModule = module((builder) => {

411

// Bind additional types for polymorphic injection

412

builder

413

.single(() => new DatabaseService())

414

.bind(IDataService)

415

.bind(ILoggable)

416

.onClose((instance) => {

417

console.log("Closing database service");

418

instance.close();

419

});

420

421

// Bind multiple types at once

422

builder

423

.factory(() => new HttpClient())

424

.binds([IHttpClient, IRequestHandler])

425

.onClose((instance) => instance.cleanup());

426

});

427

```

428

429

## Types

430

431

```javascript { .api }

432

/** Function type for module declarations */

433

type ModuleDeclaration = (builder: ModuleBuilder) => void;

434

435

/** Function type for dependency definitions */

436

type Definition<T> = (scope: Scope, parameters: ParametersHolder) => T;

437

438

/** Function type for cleanup callbacks */

439

type OnCloseCallback<T> = (instance: T) => void;

440

441

/** Module builder interface for DSL */

442

interface ModuleBuilder {

443

single<T>(definition: Definition<T>): BeanDefinition<T>;

444

single<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;

445

factory<T>(definition: Definition<T>): BeanDefinition<T>;

446

factory<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;

447

scope(qualifier: Qualifier, scopeSet: (builder: ScopeBuilder) => void): Module;

448

}

449

450

/** Scope builder interface for scoped definitions */

451

interface ScopeBuilder {

452

scoped<T>(definition: Definition<T>): BeanDefinition<T>;

453

scoped<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;

454

factory<T>(definition: Definition<T>): BeanDefinition<T>;

455

factory<T>(qualifier: Qualifier, definition: Definition<T>): BeanDefinition<T>;

456

}

457

458

/** Bean definition kinds */

459

enum BeanDefinitionKind {

460

Singleton = "Singleton",

461

Factory = "Factory",

462

Scoped = "Scoped"

463

}

464

465

/** Core bean definition class */

466

class BeanDefinition<T> {

467

scopeQualifier: Qualifier;

468

primaryType: any;

469

qualifier: Qualifier;

470

definition: Definition<T>;

471

kind: BeanDefinitionKind;

472

secondaryTypes: any[];

473

}

474

```