ts-ioc-container 23.3.4 → 23.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +54 -41
  2. package/README.template.md +453 -0
  3. package/cjs/container/AutoMockedContainer.js +15 -18
  4. package/cjs/container/AutoMockedContainer.js.map +1 -1
  5. package/cjs/container/Container.js +44 -130
  6. package/cjs/container/Container.js.map +1 -1
  7. package/cjs/container/ContainerDisposedError.js +8 -26
  8. package/cjs/container/ContainerDisposedError.js.map +1 -1
  9. package/cjs/container/DependencyNotFoundError.js +6 -24
  10. package/cjs/container/DependencyNotFoundError.js.map +1 -1
  11. package/cjs/container/EmptyContainer.js +20 -23
  12. package/cjs/container/EmptyContainer.js.map +1 -1
  13. package/cjs/container/MethodNotImplementedError.js +6 -24
  14. package/cjs/container/MethodNotImplementedError.js.map +1 -1
  15. package/cjs/injector/ProxyInjector.js +7 -25
  16. package/cjs/injector/ProxyInjector.js.map +1 -1
  17. package/cjs/injector/ReflectionInjector.js +15 -59
  18. package/cjs/injector/ReflectionInjector.js.map +1 -1
  19. package/cjs/injector/SimpleInjector.js +4 -36
  20. package/cjs/injector/SimpleInjector.js.map +1 -1
  21. package/cjs/provider/ArgsProvider.js +15 -67
  22. package/cjs/provider/ArgsProvider.js.map +1 -1
  23. package/cjs/provider/Provider.js +23 -70
  24. package/cjs/provider/Provider.js.map +1 -1
  25. package/cjs/provider/ProviderDecorator.js +12 -47
  26. package/cjs/provider/ProviderDecorator.js.map +1 -1
  27. package/cjs/provider/SingletonProvider.js +12 -60
  28. package/cjs/provider/SingletonProvider.js.map +1 -1
  29. package/cjs/provider/TaggedProvider.js +14 -36
  30. package/cjs/provider/TaggedProvider.js.map +1 -1
  31. package/cjs/reflection.js +5 -34
  32. package/cjs/reflection.js.map +1 -1
  33. package/cjs/registration/DependencyMissingKeyError.js +6 -24
  34. package/cjs/registration/DependencyMissingKeyError.js.map +1 -1
  35. package/cjs/registration/Registration.js +16 -47
  36. package/cjs/registration/Registration.js.map +1 -1
  37. package/cjs/utils.js +5 -29
  38. package/cjs/utils.js.map +1 -1
  39. package/package.json +8 -4
package/README.md CHANGED
@@ -52,21 +52,24 @@ It consists of 2 main parts:
52
52
 
53
53
  ```typescript
54
54
  import 'reflect-metadata';
55
- import { Container } from "ts-ioc-container";
55
+ import { by, Container, inject, ReflectionInjector, Provider } from 'ts-ioc-container';
56
56
 
57
- class Logger {
58
- public name = 'Logger';
59
- }
57
+ describe('Basic usage', function () {
58
+ it('should inject dependencies', function () {
59
+ class Logger {
60
+ name = 'Logger';
61
+ }
60
62
 
61
- class App {
62
- constructor(@inject(by('ILogger')) public logger: ILogger) {
63
- }
64
- }
63
+ class App {
64
+ constructor(@inject(by('ILogger')) public logger: Logger) {}
65
+ }
65
66
 
66
- const container = new Container(new ReflectionInjector()).register('ILogger', Provider.fromClass(Logger));
67
- container.resolve(App).logger.name === 'Logger'; // true
67
+ const container = new Container(new ReflectionInjector()).register('ILogger', Provider.fromClass(Logger));
68
+
69
+ expect(container.resolve(App).logger.name).toBe('Logger');
70
+ });
71
+ });
68
72
 
69
- container.dispose();
70
73
  ```
71
74
 
72
75
  ### Scopes
@@ -104,16 +107,23 @@ Sometimes you want to get all instances from container and its scopes. For examp
104
107
  - you can get instances from container and scope which were created by injector
105
108
 
106
109
  ```typescript
107
- import { Container, ReflectionInjector } from "ts-ioc-container";
110
+ import 'reflect-metadata';
111
+ import { Container, Provider, ReflectionInjector } from 'ts-ioc-container';
112
+ describe('Instances', function () {
113
+ it('should return injected instances', function () {
114
+ class Logger {}
108
115
 
109
- const container = new Container(new ReflectionInjector()).register('ILogger', Provider.fromClass(Logger));
110
- const scope = container.createScope();
116
+ const container = new Container(new ReflectionInjector()).register('ILogger', Provider.fromClass(Logger));
117
+ const scope = container.createScope();
111
118
 
112
- const logger1 = container.resolve('ILogger');
113
- const logger2 = scope.resolve('ILogger');
119
+ const logger1 = container.resolve('ILogger');
120
+ const logger2 = scope.resolve('ILogger');
121
+
122
+ expect(scope.getInstances().length).toBe(1);
123
+ expect(container.getInstances().length).toBe(2);
124
+ });
125
+ });
114
126
 
115
- expect(scope.getInstances().length).toBe(1);
116
- expect(container.getInstances().length).toBe(2);
117
127
  ```
118
128
 
119
129
  ### Disposing
@@ -464,39 +474,42 @@ for (const instance of container.getInstances()) {
464
474
  Sometimes you need to automatically mock all dependencies in container. This is what `AutoMockedContainer` is for.
465
475
 
466
476
  ```typescript
467
- import {
468
- AutoMockedContainer,
469
- Container,
470
- DependencyKey,
471
- } from "ts-ioc-container";
472
- import { Mock } from "moq.ts";
477
+ import { AutoMockedContainer, Container, DependencyKey, ReflectionInjector } from 'ts-ioc-container';
478
+ import { IMock, Mock } from 'moq.ts';
473
479
 
474
480
  export class MoqContainer extends AutoMockedContainer {
475
- private mocks = new Map<DependencyKey, IMock<any>>();
481
+ private mocks = new Map<DependencyKey, IMock<any>>();
476
482
 
477
- resolve<T>(key: DependencyKey): T {
478
- return this.resolveMock<T>(key).object();
479
- }
483
+ resolve<T>(key: DependencyKey): T {
484
+ return this.resolveMock<T>(key).object();
485
+ }
480
486
 
481
- resolveMock<T>(key: DependencyKey): IMock<T> {
482
- if (!this.mocks.has(key)) {
483
- this.mocks.set(key, new Mock());
487
+ resolveMock<T>(key: DependencyKey): IMock<T> {
488
+ if (!this.mocks.has(key)) {
489
+ this.mocks.set(key, new Mock());
490
+ }
491
+ return this.mocks.get(key) as IMock<T>;
484
492
  }
485
- return this.mocks.get(key) as IMock<T>;
486
- }
487
493
  }
488
494
 
489
- describe('test', () => {
490
- const mockContainer = new MoqContainer();
491
- const container = new Container(injector, { parent: mockContainer });
495
+ interface IEngine {
496
+ getRegistrationNumber(): string;
497
+ }
498
+
499
+ describe('Mocking', () => {
500
+ it('should auto-mock dependencies', () => {
501
+ const mockContainer = new MoqContainer();
502
+ const container = new Container(new ReflectionInjector(), { parent: mockContainer });
503
+
504
+ const engineMock = mockContainer.resolveMock<IEngine>('IEngine');
505
+ engineMock.setup((i) => i.getRegistrationNumber()).returns('123');
492
506
 
493
- const engineMock = mockContainer.resolveMock<IEngine>('IEngine');
494
- engineMock.setup(i => i.getRegistrationNumber()).return('123');
507
+ const engine = container.resolve<IEngine>('IEngine');
495
508
 
496
- const engine = container.resolve<IEngine>('IEngine');
509
+ expect(engine.getRegistrationNumber()).toBe('123');
510
+ });
511
+ });
497
512
 
498
- expect(engine.getRegistrationNumber()).toBe('123');
499
- })
500
513
  ```
501
514
 
502
515
 
@@ -0,0 +1,453 @@
1
+ # Typescript IoC (Inversion Of Control) container
2
+
3
+ ![NPM version:latest](https://img.shields.io/npm/v/ts-ioc-container/latest.svg?style=flat-square)
4
+ ![npm downloads](https://img.shields.io/npm/dt/ts-ioc-container.svg?style=flat-square)
5
+ ![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/ts-ioc-container)
6
+ [![Coverage Status](https://coveralls.io/repos/github/IgorBabkin/ts-ioc-container/badge.svg?branch=master)](https://coveralls.io/github/IgorBabkin/ts-ioc-container?branch=master)
7
+ ![License](https://img.shields.io/npm/l/ts-ioc-container)
8
+
9
+ ## Advantages
10
+ - battle tested :boom:
11
+ - written on `typescript`
12
+ - simple and lightweight (roughly it's just one file of **~100 lines**) :heart:
13
+ - clean API :green_heart:
14
+ - supports `tagged scopes`
15
+ - fully test covered :100:
16
+ - can be used with decorators `@inject`
17
+ - composable and open to extend
18
+ - awesome for testing (auto mocking)
19
+
20
+ ## Install
21
+ ```shell script
22
+ npm install ts-ioc-container reflect-metadata
23
+ ```
24
+ ```shell script
25
+ yarn add ts-ioc-container reflect-metadata
26
+ ```
27
+
28
+ ## Setup
29
+ ### reflect-metadata
30
+ Just put it in the main file of your project. It should be the first line of the code.
31
+ ```typescript
32
+ import 'reflect-metadata';
33
+ ```
34
+
35
+ ### tsconfig.json
36
+ ```json
37
+ {
38
+ "compilerOptions": {
39
+ "experimentalDecorators": true,
40
+ "emitDecoratorMetadata": true
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Container `IContainer`
46
+ It consists of 2 main parts:
47
+
48
+ - Providers - describes how to create instances of dependencies
49
+ - Injector - describes how to inject dependencies to constructor
50
+
51
+ ### Basic usage
52
+
53
+ ```typescript
54
+ {{{include_file './__tests__/readme/basic.spec.ts'}}}
55
+ ```
56
+
57
+ ### Scopes
58
+ Sometimes you need to create a scope of container. For example, when you want to create a scope per request in web application.
59
+
60
+ - NOTICE: remember that when scope doesn't have dependency then it will be resolved from parent container
61
+ - NOTICE: when you create a scope of container then all providers are cloned to new scope. For that reason every provider has methods `clone` and `isValid` to clone itself and check if it's valid for certain scope accordingly.
62
+
63
+ ```typescript
64
+ import { Container, ReflectionInjector } from "ts-ioc-container";
65
+
66
+ const container = new Container(new ReflectionInjector());
67
+ const scope = container.createScope();
68
+ ```
69
+
70
+ ### Tags
71
+ Sometimes you want to mark some providers and resolve them only from certain scope. So you can assign tags to providers and create scopes with certain tags. For that reason every scope has method `hasTag` which we invoke from provider to check if it's valid for certain scope.
72
+
73
+ - tag - is a string that we assign to provider and scope/container
74
+ - every provider can be registered per certain tags and cannot be resolved from container with other tags. Only from parent one with certain tags.
75
+ - NOTICE: when you create a scope then we clone ONLY tags-matched providers.
76
+
77
+ ```typescript
78
+ import { Container, perTags, ReflectionInjector } from "ts-ioc-container";
79
+
80
+ const container = new Container(new ReflectionInjector(), { tags: ['root'] }).register('ILogger', Provider.fromClass(Logger).pipe(perTags('root')));
81
+ const scope = container.createScope(['child']);
82
+
83
+ scope.resolve('ILogger'); // it will be resolved from container, not from scope
84
+ ```
85
+
86
+ ### Instances
87
+ Sometimes you want to get all instances from container and its scopes. For example, when you want to dispose all instances of container.
88
+
89
+ - you can get instances from container and scope which were created by injector
90
+
91
+ ```typescript
92
+ {{{include_file './__tests__/readme/instances.spec.ts'}}}
93
+ ```
94
+
95
+ ### Disposing
96
+ Sometimes you want to dispose container and all its scopes. For example, when you want to prevent memory leaks. Or you want to ensure that nobody can use container after it was disposed.
97
+
98
+ - container can be disposed
99
+ - when container is disposed then all scopes are disposed too
100
+ - when container is disposed then it unregisters all providers and remove all instances
101
+
102
+ ```typescript
103
+ import { asSingleton, Container, perTags, ReflectionInjector, ContainerDisposedError } from "ts-ioc-container";
104
+
105
+ const container = new Container(new ReflectionInjector(), { tags: ['root'] }).register('ILogger', Provider.fromClass(Logger));
106
+ const scope = container.createScope(['child']);
107
+
108
+ const logger = scope.resolve('ILogger');
109
+ container.dispose();
110
+
111
+ expect(() => scope.resolve('ILogger')).toThrow(ContainerDisposedError);
112
+ expect(() => container.resolve('ILogger')).toThrow(ContainerDisposedError);
113
+ expect(container.getInstances().length).toBe(0);
114
+ ```
115
+
116
+ ## Injectors `IInjector`
117
+ Injectors are used to describe how dependencies should be injected to constructor.
118
+
119
+ - `ReflectionInjector` - injects dependencies using `@inject` decorator
120
+ - `ProxyInjector` - injects dependencies as dictionary `Record<string, unknown>`
121
+ - `SimpleInjector` - just passes container to constructor with others arguments
122
+
123
+ ### Reflection injector
124
+ This type of injector uses `@inject` decorator to mark where dependencies should be injected. It's bases on `reflect-metadata` package. That's why I call it `ReflectionInjector`.
125
+
126
+ ```typescript
127
+ import { Container, IContainer, IInjector, Provider, by, inject, resolve } from "ts-ioc-container";
128
+
129
+ class Logger implements ILogger {
130
+ info(message: string) {
131
+ console.log(message);
132
+ }
133
+ }
134
+
135
+ class App {
136
+ constructor(@inject((container, ...args) => container.resolve('ILogger', ...args)) private logger: ILogger) {
137
+ }
138
+
139
+ // OR
140
+ // constructor(@inject(by('ILogger')) private logger: ILogger) {
141
+ // }
142
+
143
+ run() {
144
+ this.logger.info('Hello world');
145
+ }
146
+ }
147
+
148
+ const container = new Container(new ReflectionInjector())
149
+ .register('ILogger', Provider.fromClass(Logger));
150
+
151
+ const app = container.resolve(App);
152
+ app.run();
153
+ ```
154
+
155
+ ### Simple injector
156
+ This type of injector just passes container to constructor with others arguments.
157
+
158
+ ```typescript
159
+ import { SimpleInjector, IContainer } from "ts-ioc-container";
160
+
161
+ class Logger implements ILogger {
162
+ info(message: string) {
163
+ console.log(message);
164
+ }
165
+ }
166
+
167
+ class App {
168
+ private logger: ILogger;
169
+
170
+ constructor(private container: IContainer) {
171
+ this.logger = container.resolve('ILogger');
172
+ }
173
+
174
+ run() {
175
+ this.logger.info('Hello world');
176
+ }
177
+ }
178
+
179
+ const container = new Container(new SimpleInjector())
180
+ .register('ILogger', Provider.fromClass(Logger));
181
+
182
+ const app = container.resolve(App);
183
+ app.run();
184
+ ```
185
+
186
+ ### Proxy injector
187
+ This type of injector injects dependencies as dictionary `Record<string, unknown>`.
188
+
189
+ ```typescript
190
+ import { ProxyInjector, IContainer } from "ts-ioc-container";
191
+
192
+ class Logger implements ILogger {
193
+ info(message: string) {
194
+ console.log(message);
195
+ }
196
+ }
197
+
198
+ class App {
199
+ private logger: ILogger;
200
+
201
+ constructor({ logger }: { logger: ILogger }) {
202
+ this.logger = logger;
203
+ }
204
+
205
+ run() {
206
+ this.logger.info('Hello world');
207
+ }
208
+ }
209
+
210
+ const container = new Container(new ProxyInjector())
211
+ .register('logger', Provider.fromClass(Logger));
212
+
213
+ const app = container.resolve(App);
214
+ app.run();
215
+ ```
216
+
217
+ ## Providers `IProvider<T>`
218
+ Providers are used to describe how instances should be created. It has next basic methods:
219
+ - `resolve` - creates instance with passed arguments
220
+ - `clone` - we invoke it when we create a scope. It clones provider to new scope.
221
+ - `isValid` - checks if provider can be resolved from container or cloned to container with certain tags
222
+
223
+ There are next types of providers:
224
+ - `Provider` - basic provider
225
+ - `SingletonProvider` - provider that creates only one instance in every scope where it's resolved
226
+ - `TaggedProvider` - provider that can be resolved only from container with certain tags and their sub scopes
227
+ - `ArgsProvider` - provider that encapsulates arguments to pass it to constructor.
228
+
229
+ ### Provider
230
+
231
+ From function
232
+
233
+ ```typescript
234
+ import { Provider } from "ts-ioc-container";
235
+
236
+ container.register('ILogger', new Provider((container, ...args) => new Logger(container, ...args)));
237
+ ```
238
+
239
+ From class
240
+
241
+ ```typescript
242
+ import { Provider } from "ts-ioc-container";
243
+
244
+ container.register('ILogger', Provider.fromClass(Logger));
245
+ ```
246
+
247
+ From value
248
+
249
+ ```typescript
250
+ import { Provider } from "ts-ioc-container";
251
+
252
+ container.register('ILogger', Provider.fromValue(new Logger()));
253
+ ```
254
+
255
+ `pipe` - decorates provider by other providers
256
+
257
+ ```typescript
258
+ import { asSingleton, perTags, Provider, SingletonProvider, TaggedProvider } from "ts-ioc-container";
259
+
260
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new SingletonProvider(provider)), (provider) => new TaggedProvider(provider, ['root']));
261
+
262
+ // OR
263
+ container.register('ILogger', Provider.fromClass(Logger).pipe(asSingleton(), perTags('root')));
264
+
265
+ // OR
266
+ @provider(asSingleton(), perTags('root'))
267
+ class Logger {
268
+ }
269
+
270
+ container.register('ILogger', Provider.fromClass(Logger));
271
+ ```
272
+
273
+ ### Singleton provider
274
+ Sometimes you need to create only one instance of dependency per scope. For example, you want to create only one logger per scope.
275
+
276
+ - Singleton provider creates only one instance in every scope where it's resolved.
277
+ - NOTICE: if you create a scope 'A' of container 'root' then Logger of A !== Logger of root.
278
+
279
+ ```typescript
280
+ import { Provider, SingletonProvider, asSingleton } from "ts-ioc-container";
281
+
282
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new SingletonProvider(provider)));
283
+ // OR
284
+ container.register('ILogger', Provider.fromClass(Logger).pipe(asSingleton()));
285
+
286
+ container.resolve('ILogger') === container.resolve('ILogger'); // true
287
+
288
+ const scope = container.createScope();
289
+ scope.resolve('ILogger') === scope.resolve('ILogger'); // true
290
+ container.resolve('ILogger') !== scope.resolve('ILogger'); // true. NOTICE: because every provider is cloned for every child scope from parent one
291
+ ```
292
+
293
+ ### Tagged provider
294
+ Sometimes you need to resolve provider only from container with certain tags and their sub scopes. Especially if you want to register dependency as singleton for some tags, for example `root`
295
+ - NOTICE: It doesn't make clones in not tagged-matched scopes. Usually it's used with `SingletonProvider`.
296
+
297
+ ```typescript
298
+ import { Provider, TaggedProvider, asSingleton, perTags } from "ts-ioc-container";
299
+
300
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new TaggedProvider(provider, ['root'])));
301
+ // OR
302
+ container.register('ILogger', Provider.fromClass(Logger).pipe(perTags('root', 'parent')));
303
+
304
+ // with sigleton
305
+ container.register('ILogger', Provider.fromClass(Logger).pipe(perTags('root', 'parent')).pipe(asSingleton()));
306
+ container.resolve('ILogger') === container.resolve('ILogger'); // true
307
+
308
+ const scope = container.createScope();
309
+ scope.resolve('ILogger') === scope.resolve('ILogger'); // true
310
+ container.resolve('ILogger') === scope.resolve('ILogger'); // true
311
+ ```
312
+
313
+ ### Args provider
314
+ Sometimes you want to bind some arguments to provider. This is what `ArgsProvider` is for.
315
+ - NOTICE: args from this provider has higher priority than args from `resolve` method.
316
+
317
+ ```typescript
318
+ import { Provider, ArgsProvider, withArgs, withArgsFn } from "ts-ioc-container";
319
+
320
+ class Logger {
321
+ constructor(public type: string, public name: string) {
322
+ }
323
+ }
324
+
325
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new ArgsProvider(provider, () => ['FileLogger'])));
326
+
327
+ // OR
328
+ container.register('ILogger', Provider.fromClass(Logger).pipe(withArgsFn(() => ['FileLogger'])));
329
+ // OR
330
+ container.register('ILogger', Provider.fromClass(Logger).pipe(withArgs('FileLogger')));
331
+
332
+ container.resolve('ILogger', 'Main').type === 'FileLogger'; // true
333
+ container.resolve('ILogger', 'Main').name === 'Main'; // true
334
+ ```
335
+
336
+ ## Container modules
337
+ Sometimes you want to encapsulate registration logic in separate module. This is what `IContainerModule` is for.
338
+
339
+ ```typescript
340
+ import { Registration } from "ts-ioc-container";
341
+
342
+ class Development implements IContainerModule {
343
+ applyTo(container: IContainer): void {
344
+ container.add(Registration.fromClass(DevLogger));
345
+ }
346
+ }
347
+
348
+ class Production implements IContainerModule {
349
+ applyTo(container: IContainer): void {
350
+ container.add(Registration.fromClass(ProdLogger));
351
+ }
352
+ }
353
+
354
+ const container = new Container(injector, { tags: ['root'] })
355
+ .add(Registration.fromClass(Logger))
356
+ .add(process.env.NODE_ENV === 'production' ? new Production() : new Development());
357
+ ```
358
+
359
+ ## Registration module (Provider + DependencyKey)
360
+ Sometimes you need to keep dependency key with class together. For example, you want to register class with key 'ILogger' and you want to keep this key with class. This is what `Registration` is for.
361
+
362
+ ```typescript
363
+ import { asSingleton, perTags, forKey, Registration, Provider } from "ts-ioc-container";
364
+
365
+ @forKey('ILogger')
366
+ @provider(asSingleton(), perTags('root'))
367
+ class Logger {
368
+ info(message: string) {
369
+ console.log(message);
370
+ }
371
+ }
372
+
373
+ container.register(Registration.fromClass(Logger));
374
+
375
+ // OR
376
+
377
+ @provider(asSingleton(), perTags('root'))
378
+ class Logger {
379
+ info(message: string) {
380
+ console.log(message);
381
+ }
382
+ }
383
+
384
+ container.register('ILogger', Provider.fromClass(Logger));
385
+ ```
386
+
387
+ ## Hooks
388
+ Sometimes you need to invoke methods after construct or dispose of class. This is what hooks are for.
389
+
390
+ ```typescript
391
+ import {
392
+ Container,
393
+ IInjector,
394
+ ContainerHook,
395
+ Injector,
396
+ Registration,
397
+ getHooks,
398
+ hook,
399
+ } from "ts-ioc-container";
400
+
401
+ class MyInjector implements IInjector {
402
+ private injector = new ReflectionInjector();
403
+
404
+ resolve<T>(container: IContainer, value: constructor<T>, ...deps: unknown[]): T {
405
+ const instance = this.injector.resolve(container, value, ...deps);
406
+ for (const h of getHooks(instance, 'onConstruct')) {
407
+ // @ts-ignore
408
+ instance[h]();
409
+ }
410
+ return instance;
411
+ }
412
+ }
413
+
414
+ @forKey('ILogger')
415
+ class Logger {
416
+ @hook('onConstruct')
417
+ initialize() {
418
+ console.log('initialized');
419
+ }
420
+
421
+ @hook('onDispose')
422
+ dispose() {
423
+ console.log('disposed');
424
+ }
425
+ }
426
+
427
+ const container = new Container(new MyInjector())
428
+ .add(Registration.fromClass(Logger));
429
+ const logger = container.resolve<ILogger>('ILogger'); // initialized
430
+
431
+ for (const instance of container.getInstances()) {
432
+ for (const h of getHooks(instance, 'onDispose')) {
433
+ // @ts-ignore
434
+ instance[h](); // disposed
435
+ }
436
+ }
437
+ ```
438
+
439
+ ## Mocking / Tests `AutoMockedContainer`
440
+ Sometimes you need to automatically mock all dependencies in container. This is what `AutoMockedContainer` is for.
441
+
442
+ ```typescript
443
+ {{{include_file '__tests__/readme/mocking.spec.ts'}}}
444
+ ```
445
+
446
+
447
+ ## Errors
448
+
449
+ - [DependencyNotFoundError.ts](lib%2Fcontainer%2FDependencyNotFoundError.ts)
450
+ - [DependencyMissingKeyError.ts](lib%2Fregistration%2FDependencyMissingKeyError.ts)
451
+ - [MethodNotImplementedError.ts](lib%2FMethodNotImplementedError.ts)
452
+ - [ContainerDisposedError.ts](lib%2Fcontainer%2FContainerDisposedError.ts)
453
+
@@ -1,28 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AutoMockedContainer = void 0;
4
- var index_1 = require("../index");
5
- var AutoMockedContainer = /** @class */ (function () {
6
- function AutoMockedContainer() {
7
- }
8
- AutoMockedContainer.prototype.createScope = function () {
4
+ const index_1 = require("../index");
5
+ class AutoMockedContainer {
6
+ createScope() {
9
7
  throw new index_1.MethodNotImplementedError();
10
- };
11
- AutoMockedContainer.prototype.dispose = function () { };
12
- AutoMockedContainer.prototype.getProviders = function () {
8
+ }
9
+ dispose() { }
10
+ getProviders() {
13
11
  return new Map();
14
- };
15
- AutoMockedContainer.prototype.register = function () {
12
+ }
13
+ register() {
16
14
  throw new index_1.MethodNotImplementedError();
17
- };
18
- AutoMockedContainer.prototype.getInstances = function () {
15
+ }
16
+ getInstances() {
19
17
  return [];
20
- };
21
- AutoMockedContainer.prototype.removeScope = function () { };
22
- AutoMockedContainer.prototype.add = function () {
18
+ }
19
+ removeScope() { }
20
+ add() {
23
21
  throw new index_1.MethodNotImplementedError();
24
- };
25
- return AutoMockedContainer;
26
- }());
22
+ }
23
+ }
27
24
  exports.AutoMockedContainer = AutoMockedContainer;
28
25
  //# sourceMappingURL=AutoMockedContainer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AutoMockedContainer.js","sourceRoot":"","sources":["../../lib/container/AutoMockedContainer.ts"],"names":[],"mappings":";;;AAAA,kCAA2G;AAE3G;IAAA;IA0BA,CAAC;IAzBG,yCAAW,GAAX;QACI,MAAM,IAAI,iCAAyB,EAAE,CAAC;IAC1C,CAAC;IAID,qCAAO,GAAP,cAAiB,CAAC;IAElB,0CAAY,GAAZ;QACI,OAAO,IAAI,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,sCAAQ,GAAR;QACI,MAAM,IAAI,iCAAyB,EAAE,CAAC;IAC1C,CAAC;IAED,0CAAY,GAAZ;QACI,OAAO,EAAE,CAAC;IACd,CAAC;IAED,yCAAW,GAAX,cAAqB,CAAC;IAEtB,iCAAG,GAAH;QACI,MAAM,IAAI,iCAAyB,EAAE,CAAC;IAC1C,CAAC;IACL,0BAAC;AAAD,CAAC,AA1BD,IA0BC;AA1BqB,kDAAmB"}
1
+ {"version":3,"file":"AutoMockedContainer.js","sourceRoot":"","sources":["../../lib/container/AutoMockedContainer.ts"],"names":[],"mappings":";;;AAAA,oCAA2G;AAE3G,MAAsB,mBAAmB;IACrC,WAAW;QACP,MAAM,IAAI,iCAAyB,EAAE,CAAC;IAC1C,CAAC;IAID,OAAO,KAAU,CAAC;IAElB,YAAY;QACR,OAAO,IAAI,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,QAAQ;QACJ,MAAM,IAAI,iCAAyB,EAAE,CAAC;IAC1C,CAAC;IAED,YAAY;QACR,OAAO,EAAE,CAAC;IACd,CAAC;IAED,WAAW,KAAU,CAAC;IAEtB,GAAG;QACC,MAAM,IAAI,iCAAyB,EAAE,CAAC;IAC1C,CAAC;CACJ;AA1BD,kDA0BC"}