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
```