ts-ioc-container 27.4.0 → 27.4.2

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.
package/README.md CHANGED
@@ -30,21 +30,20 @@
30
30
  - [Simple injector](#simple-injector)
31
31
  - [Proxy injector](#proxy-injector)
32
32
  - [Providers](#providers)
33
+ - [Registration module (Provider + DependencyKey)](#registration-and-providers) `@key`
33
34
  - [Provider](#provider) `@provider`
34
35
  - [Singleton provider](#singleton-provider)
35
36
  - [Tagged provider](#tagged-provider)
36
37
  - [Args provider](#args-provider)
37
38
  - [Aliases](#aliases) `alias`
38
39
  - [Container modules](#container-modules)
39
- - [Basic usage](#basic-usage-1)
40
- - [Registration module (Provider + DependencyKey)](#registration-module-provider--dependencykey) `@key`
41
40
  - [Hooks](#hooks) `@hook`
42
41
  - [OnConstruct](#onconstruct) `@onConstruct`
43
42
  - [OnDispose](#ondispose) `@onDispose`
44
43
  - [Tests and Mocks](#tests-and-mocks)
45
44
  - [Errors](#errors)
46
45
 
47
- ## Setup
46
+ ## Setu
48
47
 
49
48
  ```shell script
50
49
  npm install ts-ioc-container reflect-metadata
@@ -78,16 +77,7 @@ And `tsconfig.json` should have next options:
78
77
 
79
78
  ```typescript
80
79
  import 'reflect-metadata';
81
- import {
82
- IContainer,
83
- by,
84
- Container,
85
- inject,
86
- ReflectionInjector,
87
- RegistrationConflictError,
88
- Registration,
89
- key,
90
- } from 'ts-ioc-container';
80
+ import { IContainer, by, Container, inject, ReflectionInjector, Registration as R } from 'ts-ioc-container';
91
81
 
92
82
  describe('Basic usage', function () {
93
83
  class Logger {
@@ -99,7 +89,7 @@ describe('Basic usage', function () {
99
89
  constructor(@inject(by.key('ILogger')) public logger: Logger) {}
100
90
  }
101
91
 
102
- const container = new Container(new ReflectionInjector()).use(Registration.fromClass(Logger).to('ILogger'));
92
+ const container = new Container(new ReflectionInjector()).use(R.fromClass(Logger).to('ILogger'));
103
93
 
104
94
  expect(container.resolve(App).logger.name).toBe('Logger');
105
95
  });
@@ -110,8 +100,8 @@ describe('Basic usage', function () {
110
100
  }
111
101
 
112
102
  const container = new Container(new ReflectionInjector())
113
- .use(Registration.fromClass(Logger).to('ILogger1'))
114
- .use(Registration.fromClass(Logger).to('ILogger2'));
103
+ .use(R.fromClass(Logger).to('ILogger1'))
104
+ .use(R.fromClass(Logger).to('ILogger2'));
115
105
 
116
106
  expect(container.resolve(App).loggers).toHaveLength(2);
117
107
  });
@@ -127,46 +117,6 @@ describe('Basic usage', function () {
127
117
 
128
118
  expect(app.scope).toBe(root);
129
119
  });
130
-
131
- it('should not raise an error when key is busy', () => {
132
- expect(() => {
133
- new Container(new ReflectionInjector()).use(Registration.fromClass(Logger)).use(Registration.fromClass(Logger));
134
- }).not.toThrowError(RegistrationConflictError);
135
- });
136
-
137
- it('registration -> should raise an error when key is busy', () => {
138
- expect(() => {
139
- new Container(new ReflectionInjector())
140
- .use(Registration.fromClass(Logger))
141
- .use(Registration.fromClass(Logger).throwErrorOnConflict());
142
- }).toThrowError(RegistrationConflictError);
143
- });
144
-
145
- it('registration -> should not raise an error when key is busy', () => {
146
- expect(() => {
147
- new Container(new ReflectionInjector()).use(Registration.fromClass(Logger)).use(Registration.fromClass(Logger));
148
- }).not.toThrowError(RegistrationConflictError);
149
- });
150
-
151
- it('@key -> should raise an error when key is busy', () => {
152
- @key('Logger')
153
- class Logger1 {}
154
-
155
- @key('Logger')
156
- class Logger2 {}
157
-
158
- expect(() => {
159
- new Container(new ReflectionInjector())
160
- .use(Registration.fromClass(Logger1))
161
- .use(Registration.fromClass(Logger2).throwErrorOnConflict());
162
- }).toThrowError(RegistrationConflictError);
163
- });
164
-
165
- it('registration -> should not raise an error when key is busy', () => {
166
- expect(() => {
167
- new Container(new ReflectionInjector()).use(Registration.fromClass(Logger)).use(Registration.fromClass(Logger));
168
- }).not.toThrowError(RegistrationConflictError);
169
- });
170
120
  });
171
121
 
172
122
  ```
@@ -190,7 +140,7 @@ import {
190
140
  tags,
191
141
  provider,
192
142
  ReflectionInjector,
193
- Registration,
143
+ Registration as R,
194
144
  by,
195
145
  } from 'ts-ioc-container';
196
146
 
@@ -200,7 +150,7 @@ class Logger {}
200
150
 
201
151
  describe('Scopes', function () {
202
152
  it('should resolve dependencies from scope', function () {
203
- const root = new Container(new ReflectionInjector(), { tags: ['root'] }).use(Registration.fromClass(Logger));
153
+ const root = new Container(new ReflectionInjector(), { tags: ['root'] }).use(R.fromClass(Logger));
204
154
  const child = root.createScope('child');
205
155
 
206
156
  expect(child.resolve('ILogger')).toBe(child.resolve('ILogger'));
@@ -230,14 +180,14 @@ Sometimes you want to get all instances from container and its scopes. For examp
230
180
 
231
181
  ```typescript
232
182
  import 'reflect-metadata';
233
- import { inject, key, Registration, Container, ReflectionInjector, by } from 'ts-ioc-container';
183
+ import { inject, key, Registration as R, Container, ReflectionInjector, by } from 'ts-ioc-container';
234
184
 
235
185
  describe('Instances', function () {
236
186
  @key('ILogger')
237
187
  class Logger {}
238
188
 
239
189
  it('should return injected instances', () => {
240
- const container = new Container(new ReflectionInjector()).use(Registration.fromClass(Logger));
190
+ const container = new Container(new ReflectionInjector()).use(R.fromClass(Logger));
241
191
  const scope = container.createScope();
242
192
 
243
193
  const logger1 = container.resolve('ILogger');
@@ -254,7 +204,7 @@ describe('Instances', function () {
254
204
  constructor(@inject(by.instances(isLogger)) public loggers: Logger[]) {}
255
205
  }
256
206
 
257
- const container = new Container(new ReflectionInjector()).use(Registration.fromClass(Logger));
207
+ const container = new Container(new ReflectionInjector()).use(R.fromClass(Logger));
258
208
 
259
209
  const logger0 = container.resolve('ILogger');
260
210
  const logger1 = container.resolve('ILogger');
@@ -277,15 +227,13 @@ Sometimes you want to dispose container and all its scopes. For example, when yo
277
227
 
278
228
  ```typescript
279
229
  import 'reflect-metadata';
280
- import { Container, ContainerDisposedError, ReflectionInjector, Registration } from 'ts-ioc-container';
230
+ import { Container, ContainerDisposedError, ReflectionInjector, Registration as R } from 'ts-ioc-container';
281
231
 
282
232
  class Logger {}
283
233
 
284
234
  describe('Disposing', function () {
285
235
  it('should container and make it unavailable for the further usage', function () {
286
- const root = new Container(new ReflectionInjector(), { tags: ['root'] }).use(
287
- Registration.fromClass(Logger).to('ILogger'),
288
- );
236
+ const root = new Container(new ReflectionInjector(), { tags: ['root'] }).use(R.fromClass(Logger).to('ILogger'));
289
237
  const child = root.createScope('child');
290
238
 
291
239
  const logger = child.resolve('ILogger');
@@ -311,7 +259,7 @@ This type of injector uses `@inject` decorator to mark where dependencies should
311
259
 
312
260
  ```typescript
313
261
  import 'reflect-metadata';
314
- import { by, Container, inject, ReflectionInjector, Registration } from 'ts-ioc-container';
262
+ import { by, Container, inject, ReflectionInjector, Registration as R } from 'ts-ioc-container';
315
263
 
316
264
  class Logger {
317
265
  name = 'Logger';
@@ -331,7 +279,7 @@ class App {
331
279
 
332
280
  describe('Reflection Injector', function () {
333
281
  it('should inject dependencies by @inject decorator', function () {
334
- const container = new Container(new ReflectionInjector()).use(Registration.fromClass(Logger).to('ILogger'));
282
+ const container = new Container(new ReflectionInjector()).use(R.fromClass(Logger).to('ILogger'));
335
283
 
336
284
  const app = container.resolve(App);
337
285
 
@@ -346,7 +294,7 @@ This type of injector just passes container to constructor with others arguments
346
294
 
347
295
  ```typescript
348
296
  import 'reflect-metadata';
349
- import { Container, IContainer, Registration, SimpleInjector } from 'ts-ioc-container';
297
+ import { Container, IContainer, Registration as R, SimpleInjector } from 'ts-ioc-container';
350
298
 
351
299
  describe('SimpleInjector', function () {
352
300
  it('should pass container as first parameter', function () {
@@ -354,7 +302,7 @@ describe('SimpleInjector', function () {
354
302
  constructor(public container: IContainer) {}
355
303
  }
356
304
 
357
- const container = new Container(new SimpleInjector()).use(Registration.fromClass(App).to('App'));
305
+ const container = new Container(new SimpleInjector()).use(R.fromClass(App).to('App'));
358
306
  const app = container.resolve<App>('App');
359
307
 
360
308
  expect(app.container).toBeInstanceOf(Container);
@@ -365,7 +313,7 @@ describe('SimpleInjector', function () {
365
313
  constructor(container: IContainer, public greeting: string) {}
366
314
  }
367
315
 
368
- const container = new Container(new SimpleInjector()).use(Registration.fromClass(App).to('App'));
316
+ const container = new Container(new SimpleInjector()).use(R.fromClass(App).to('App'));
369
317
  const app = container.resolve<App>('App', 'Hello world');
370
318
 
371
319
  expect(app.greeting).toBe('Hello world');
@@ -379,7 +327,7 @@ This type of injector injects dependencies as dictionary `Record<string, unknown
379
327
 
380
328
  ```typescript
381
329
  import 'reflect-metadata';
382
- import { Container, ProxyInjector, args, Registration } from 'ts-ioc-container';
330
+ import { Container, ProxyInjector, args, Registration as R } from 'ts-ioc-container';
383
331
 
384
332
  describe('ProxyInjector', function () {
385
333
  it('should pass dependency to constructor as dictionary', function () {
@@ -393,7 +341,7 @@ describe('ProxyInjector', function () {
393
341
  }
394
342
  }
395
343
 
396
- const container = new Container(new ProxyInjector()).use(Registration.fromClass(Logger).to('logger'));
344
+ const container = new Container(new ProxyInjector()).use(R.fromClass(Logger).to('logger'));
397
345
 
398
346
  const app = container.resolve(App);
399
347
  expect(app.logger).toBeInstanceOf(Logger);
@@ -423,8 +371,8 @@ describe('ProxyInjector', function () {
423
371
  const greetingTemplate = (name: string) => `Hello ${name}`;
424
372
 
425
373
  const container = new Container(new ProxyInjector())
426
- .use(Registration.fromClass(App).to('App').pipe(args({ greetingTemplate })))
427
- .use(Registration.fromClass(Logger).to('logger'));
374
+ .use(R.fromClass(App).to('App').pipe(args({ greetingTemplate })))
375
+ .use(R.fromClass(Logger).to('logger'));
428
376
 
429
377
  const app = container.resolve<App>('App', { name: `world` });
430
378
  expect(app.greeting).toBe('Hello world');
@@ -433,7 +381,7 @@ describe('ProxyInjector', function () {
433
381
 
434
382
  ```
435
383
 
436
- ## Providers
384
+ ## Registration and Providers
437
385
  `IProvider<T>` is used to describe how instances should be created. It has next basic methods:
438
386
  - `resolve` - creates instance with passed arguments
439
387
  - `clone` - we invoke it when we create a scope. It clones provider to new scope.
@@ -445,6 +393,58 @@ There are next types of providers:
445
393
  - `TaggedProvider` - provider that can be resolved only from container with certain tags and their sub scopes
446
394
  - `ArgsProvider` - provider that encapsulates arguments to pass it to constructor.
447
395
 
396
+ `Registration` - just a helper to register provider with certain key. `(preferrably to use)`
397
+
398
+ ### Registration (Provider + DependencyKey)
399
+ 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.
400
+
401
+ ```typescript
402
+ import 'reflect-metadata';
403
+ import { singleton, Container, tags, provider, ReflectionInjector, Registration as R, key } from 'ts-ioc-container';
404
+ import { DependencyMissingKeyError } from '../../lib/errors/DependencyMissingKeyError';
405
+
406
+ describe('Registration module', function () {
407
+ const createContainer = () => new Container(new ReflectionInjector(), { tags: ['root'] });
408
+
409
+ it('should register class', function () {
410
+ @key('ILogger')
411
+ @provider(singleton(), tags('root'))
412
+ class Logger {}
413
+
414
+ const root = createContainer().use(R.fromClass(Logger));
415
+
416
+ expect(root.resolve('ILogger')).toBeInstanceOf(Logger);
417
+ });
418
+
419
+ it('should register value', function () {
420
+ const root = createContainer().use(R.fromValue('smth').to('ISmth'));
421
+
422
+ expect(root.resolve('ISmth')).toBe('smth');
423
+ });
424
+
425
+ it('should register fn', function () {
426
+ const root = createContainer().use(R.fromFn(() => 'smth').to('ISmth'));
427
+
428
+ expect(root.resolve('ISmth')).toBe('smth');
429
+ });
430
+
431
+ it('should raise an error if key is not provider', () => {
432
+ expect(() => {
433
+ createContainer().use(R.fromValue('smth'));
434
+ }).toThrowError(DependencyMissingKeyError);
435
+ });
436
+
437
+ it('should register dependency by class name if @key is not provided', function () {
438
+ class FileLogger {}
439
+
440
+ const root = createContainer().use(R.fromClass(FileLogger));
441
+
442
+ expect(root.resolve('FileLogger')).toBeInstanceOf(FileLogger);
443
+ });
444
+ });
445
+
446
+ ```
447
+
448
448
  ### Provider
449
449
 
450
450
  ```typescript
@@ -492,7 +492,7 @@ Sometimes you need to create only one instance of dependency per scope. For exam
492
492
 
493
493
  ```typescript
494
494
  import 'reflect-metadata';
495
- import { singleton, Container, key, provider, ReflectionInjector, Registration } from 'ts-ioc-container';
495
+ import { singleton, Container, key, provider, ReflectionInjector, Registration as R } from 'ts-ioc-container';
496
496
 
497
497
  @key('logger')
498
498
  @provider(singleton())
@@ -504,20 +504,20 @@ describe('Singleton', function () {
504
504
  }
505
505
 
506
506
  it('should resolve the same container per every request', function () {
507
- const container = createContainer().use(Registration.fromClass(Logger));
507
+ const container = createContainer().use(R.fromClass(Logger));
508
508
 
509
509
  expect(container.resolve('logger')).toBe(container.resolve('logger'));
510
510
  });
511
511
 
512
512
  it('should resolve different dependency per scope', function () {
513
- const container = createContainer().use(Registration.fromClass(Logger));
513
+ const container = createContainer().use(R.fromClass(Logger));
514
514
  const child = container.createScope();
515
515
 
516
516
  expect(container.resolve('logger')).not.toBe(child.resolve('logger'));
517
517
  });
518
518
 
519
519
  it('should resolve the same dependency for scope', function () {
520
- const container = createContainer().use(Registration.fromClass(Logger));
520
+ const container = createContainer().use(R.fromClass(Logger));
521
521
  const child = container.createScope();
522
522
 
523
523
  expect(child.resolve('logger')).toBe(child.resolve('logger'));
@@ -532,14 +532,14 @@ Sometimes you need to resolve provider only from container with certain tags and
532
532
 
533
533
  ```typescript
534
534
  import 'reflect-metadata';
535
- import { singleton, Container, key, tags, provider, ReflectionInjector, Registration } from 'ts-ioc-container';
535
+ import { singleton, Container, key, tags, provider, ReflectionInjector, Registration as R } from 'ts-ioc-container';
536
536
 
537
537
  @key('ILogger')
538
538
  @provider(singleton(), tags('root')) // the same as .pipe(singleton(), tags('root'))
539
539
  class Logger {}
540
540
  describe('TaggedProvider', function () {
541
541
  it('should return the same instance', function () {
542
- const root = new Container(new ReflectionInjector(), { tags: ['root'] }).use(Registration.fromClass(Logger));
542
+ const root = new Container(new ReflectionInjector(), { tags: ['root'] }).use(R.fromClass(Logger));
543
543
  const child = root.createScope();
544
544
  expect(root.resolve('ILogger')).toBe(child.resolve('ILogger'));
545
545
  });
@@ -553,7 +553,7 @@ Sometimes you want to bind some arguments to provider. This is what `ArgsProvide
553
553
 
554
554
  ```typescript
555
555
  import 'reflect-metadata';
556
- import { Container, key, argsFn, args, ReflectionInjector, Registration } from 'ts-ioc-container';
556
+ import { Container, key, argsFn, args, ReflectionInjector, Registration as R } from 'ts-ioc-container';
557
557
 
558
558
  @key('logger')
559
559
  class Logger {
@@ -566,21 +566,21 @@ describe('ArgsProvider', function () {
566
566
  }
567
567
 
568
568
  it('can assign argument function to provider', function () {
569
- const root = createContainer().use(Registration.fromClass(Logger).pipe(argsFn((container, ...args) => ['name'])));
569
+ const root = createContainer().use(R.fromClass(Logger).pipe(argsFn((container, ...args) => ['name'])));
570
570
 
571
571
  const logger = root.createScope().resolve<Logger>('logger');
572
572
  expect(logger.name).toBe('name');
573
573
  });
574
574
 
575
575
  it('can assign argument to provider', function () {
576
- const root = createContainer().use(Registration.fromClass(Logger).pipe(args('name')));
576
+ const root = createContainer().use(R.fromClass(Logger).pipe(args('name')));
577
577
 
578
578
  const logger = root.resolve<Logger>('logger');
579
579
  expect(logger.name).toBe('name');
580
580
  });
581
581
 
582
582
  it('should set provider arguments with highest priority in compare to resolve arguments', function () {
583
- const root = createContainer().use(Registration.fromClass(Logger).pipe(args('name')));
583
+ const root = createContainer().use(R.fromClass(Logger).pipe(args('name')));
584
584
 
585
585
  const logger = root.resolve<Logger>('logger', 'file');
586
586
 
@@ -599,7 +599,7 @@ Sometimes you want to register the same provider with different keys. This is wh
599
599
 
600
600
  ```typescript
601
601
  import 'reflect-metadata';
602
- import { alias, by, Container, inject, provider, ReflectionInjector, Registration } from 'ts-ioc-container';
602
+ import { alias, by, Container, inject, provider, ReflectionInjector, Registration as R } from 'ts-ioc-container';
603
603
 
604
604
  describe('alias', () => {
605
605
  const IMiddlewareKey = Symbol('IMiddleware');
@@ -653,8 +653,8 @@ describe('alias', () => {
653
653
  }
654
654
 
655
655
  const container = new Container(new ReflectionInjector())
656
- .use(Registration.fromClass(LoggerMiddleware))
657
- .use(Registration.fromClass(ErrorHandlerMiddleware));
656
+ .use(R.fromClass(LoggerMiddleware))
657
+ .use(R.fromClass(ErrorHandlerMiddleware));
658
658
 
659
659
  const app = container.resolve(App);
660
660
  app.run();
@@ -669,11 +669,9 @@ describe('alias', () => {
669
669
  ## Container modules
670
670
  Sometimes you want to encapsulate registration logic in separate module. This is what `IContainerModule` is for.
671
671
 
672
- ### Basic usage
673
-
674
672
  ```typescript
675
673
  import 'reflect-metadata';
676
- import { IContainerModule, Registration, IContainer, key, Container, ReflectionInjector } from 'ts-ioc-container';
674
+ import { IContainerModule, Registration as R, IContainer, key, Container, ReflectionInjector } from 'ts-ioc-container';
677
675
 
678
676
  @key('ILogger')
679
677
  class Logger {}
@@ -683,13 +681,13 @@ class TestLogger {}
683
681
 
684
682
  class Production implements IContainerModule {
685
683
  applyTo(container: IContainer): void {
686
- container.use(Registration.fromClass(Logger));
684
+ container.use(R.fromClass(Logger));
687
685
  }
688
686
  }
689
687
 
690
688
  class Development implements IContainerModule {
691
689
  applyTo(container: IContainer): void {
692
- container.use(Registration.fromClass(TestLogger));
690
+ container.use(R.fromClass(TestLogger));
693
691
  }
694
692
  }
695
693
 
@@ -713,37 +711,6 @@ describe('Container Modules', function () {
713
711
 
714
712
  ```
715
713
 
716
- ### Registration module (Provider + DependencyKey)
717
- 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.
718
-
719
- ```typescript
720
- import 'reflect-metadata';
721
- import { singleton, Container, tags, provider, ReflectionInjector, Registration, key } from 'ts-ioc-container';
722
-
723
- describe('Registration module', function () {
724
- const createContainer = () => new Container(new ReflectionInjector(), { tags: ['root'] });
725
-
726
- it('should register dependency by @key', function () {
727
- @key('ILogger')
728
- @provider(singleton(), tags('root'))
729
- class Logger {}
730
-
731
- const root = createContainer().use(Registration.fromClass(Logger));
732
-
733
- expect(root.resolve('ILogger')).toBeInstanceOf(Logger);
734
- });
735
-
736
- it('should register dependency by class name if @key is not provided', function () {
737
- class FileLogger {}
738
-
739
- const root = createContainer().use(Registration.fromClass(FileLogger));
740
-
741
- expect(root.resolve('FileLogger')).toBeInstanceOf(FileLogger);
742
- });
743
- });
744
-
745
- ```
746
-
747
714
  ## Hooks
748
715
  Sometimes you need to invoke methods after construct or dispose of class. This is what hooks are for.
749
716
 
@@ -759,7 +726,7 @@ import {
759
726
  IContainer,
760
727
  IInjector,
761
728
  ReflectionInjector,
762
- Registration,
729
+ Registration as R,
763
730
  } from 'ts-ioc-container';
764
731
 
765
732
  class MyInjector implements IInjector {
@@ -792,7 +759,7 @@ class Logger {
792
759
 
793
760
  describe('onConstruct', function () {
794
761
  it('should make logger be ready on resolve', function () {
795
- const container = new Container(new MyInjector()).use(Registration.fromClass(Logger));
762
+ const container = new Container(new MyInjector()).use(R.fromClass(Logger));
796
763
 
797
764
  const logger = container.resolve<Logger>('logger');
798
765
 
@@ -814,7 +781,7 @@ import {
814
781
  hook,
815
782
  inject,
816
783
  provider,
817
- Registration,
784
+ Registration as R,
818
785
  ReflectionInjector,
819
786
  } from 'ts-ioc-container';
820
787
 
@@ -847,9 +814,7 @@ class Logger {
847
814
 
848
815
  describe('onDispose', function () {
849
816
  it('should invoke hooks on all instances', async function () {
850
- const container = new Container(new ReflectionInjector())
851
- .use(Registration.fromClass(Logger))
852
- .use(Registration.fromClass(LogsRepo));
817
+ const container = new Container(new ReflectionInjector()).use(R.fromClass(Logger)).use(R.fromClass(LogsRepo));
853
818
 
854
819
  const logger = container.resolve<Logger>('logger');
855
820
  logger.log('Hello');
@@ -67,8 +67,10 @@ class Container {
67
67
  hasTag(tag) {
68
68
  return this.tags.includes(tag);
69
69
  }
70
- use(module) {
71
- module.applyTo(this);
70
+ use(...modules) {
71
+ for (const module of modules) {
72
+ module.applyTo(this);
73
+ }
72
74
  return this;
73
75
  }
74
76
  hasDependency(key) {
package/cjm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMetadata = exports.setMetadata = exports.by = exports.hook = exports.getHooks = exports.ProxyInjector = exports.SimpleInjector = exports.inject = exports.ReflectionInjector = exports.Registration = exports.key = exports.AutoMockedContainer = exports.TaggedProvider = exports.tags = exports.SingletonProvider = exports.singleton = exports.ArgsProvider = exports.args = exports.argsFn = exports.provider = exports.Provider = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.alias = exports.EmptyContainer = exports.Container = exports.isDependencyKey = void 0;
3
+ exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.by = exports.hook = exports.getHooks = exports.ProxyInjector = exports.SimpleInjector = exports.inject = exports.ReflectionInjector = exports.Registration = exports.key = exports.AutoMockedContainer = exports.TaggedProvider = exports.tags = exports.SingletonProvider = exports.singleton = exports.ArgsProvider = exports.args = exports.argsFn = exports.provider = exports.Provider = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.alias = exports.EmptyContainer = exports.Container = exports.isDependencyKey = void 0;
4
4
  var IContainer_1 = require("./container/IContainer");
5
5
  Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
6
6
  var Container_1 = require("./container/Container");
@@ -48,3 +48,4 @@ Object.defineProperty(exports, "by", { enumerable: true, get: function () { retu
48
48
  var metadata_1 = require("./metadata");
49
49
  Object.defineProperty(exports, "setMetadata", { enumerable: true, get: function () { return metadata_1.setMetadata; } });
50
50
  Object.defineProperty(exports, "getMetadata", { enumerable: true, get: function () { return metadata_1.getMetadata; } });
51
+ Object.defineProperty(exports, "setParameterMetadata", { enumerable: true, get: function () { return metadata_1.setParameterMetadata; } });
@@ -2,19 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ReflectionInjector = exports.inject = void 0;
4
4
  const utils_1 = require("../utils");
5
+ const metadata_1 = require("../metadata");
5
6
  const INJECT_KEY = 'INJECT_FN_LIST';
6
- const inject = (value) => (target, propertyKey, parameterIndex) => {
7
- var _a;
8
- const metadata = (_a = Reflect.getOwnMetadata(INJECT_KEY, target)) !== null && _a !== void 0 ? _a : [];
9
- metadata[parameterIndex] = value;
10
- Reflect.defineMetadata(INJECT_KEY, metadata, target);
11
- };
7
+ const inject = (value) => (0, metadata_1.setParameterMetadata)(INJECT_KEY, value);
12
8
  exports.inject = inject;
13
9
  class ReflectionInjector {
14
10
  resolve(container, Target, ...deps) {
15
11
  var _a;
16
12
  const injectionFns = (_a = Reflect.getOwnMetadata(INJECT_KEY, Target)) !== null && _a !== void 0 ? _a : [];
17
- const args = (0, utils_1.merge)(injectionFns, deps.map(utils_1.constant)).map((fn) => fn(container));
13
+ const args = (0, utils_1.fillEmptyIndexes)(injectionFns, deps.map(utils_1.constant)).map((fn) => fn(container));
18
14
  return new Target(...args);
19
15
  }
20
16
  }
package/cjm/metadata.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMetadata = exports.setMetadata = void 0;
3
+ exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = void 0;
4
4
  const setMetadata = (key, value) => (target) => {
5
5
  Reflect.defineMetadata(key, value, target);
6
6
  };
@@ -10,3 +10,10 @@ function getMetadata(target, key) {
10
10
  return Reflect.getOwnMetadata(key, target);
11
11
  }
12
12
  exports.getMetadata = getMetadata;
13
+ const setParameterMetadata = (key, value) => (target, propertyKey, parameterIndex) => {
14
+ var _a;
15
+ const metadata = (_a = Reflect.getOwnMetadata(key, target)) !== null && _a !== void 0 ? _a : [];
16
+ metadata[parameterIndex] = value;
17
+ Reflect.defineMetadata(key, metadata, target);
18
+ };
19
+ exports.setParameterMetadata = setParameterMetadata;
package/cjm/utils.js CHANGED
@@ -1,23 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.constant = exports.merge = exports.pipe = void 0;
3
+ exports.constant = exports.fillEmptyIndexes = exports.pipe = void 0;
4
4
  function pipe(...mappers) {
5
5
  return (value) => mappers.reduce((acc, current) => current(acc), value);
6
6
  }
7
7
  exports.pipe = pipe;
8
- function merge(baseArr, insertArr) {
9
- if (baseArr.length === 0) {
10
- return insertArr;
8
+ function fillEmptyIndexes(baseArr, insertArr) {
9
+ const a = [...baseArr];
10
+ const b = [...insertArr];
11
+ for (let i = 0; i < a.length; i++) {
12
+ if (a[i] === undefined) {
13
+ a[i] = b.shift();
14
+ }
11
15
  }
12
- if (insertArr.length === 0) {
13
- return baseArr;
14
- }
15
- const [b1, ...restBaseArr] = baseArr;
16
- const [i1, ...restInsertArr] = insertArr;
17
- return b1 === undefined
18
- ? [i1].concat(merge(restBaseArr, restInsertArr))
19
- : [b1].concat(merge(restBaseArr, insertArr));
16
+ return a.concat(b);
20
17
  }
21
- exports.merge = merge;
18
+ exports.fillEmptyIndexes = fillEmptyIndexes;
22
19
  const constant = (value) => () => value;
23
20
  exports.constant = constant;
@@ -64,8 +64,10 @@ export class Container {
64
64
  hasTag(tag) {
65
65
  return this.tags.includes(tag);
66
66
  }
67
- use(module) {
68
- module.applyTo(this);
67
+ use(...modules) {
68
+ for (const module of modules) {
69
+ module.applyTo(this);
70
+ }
69
71
  return this;
70
72
  }
71
73
  hasDependency(key) {
package/esm/index.js CHANGED
@@ -16,4 +16,4 @@ export { SimpleInjector } from './injector/SimpleInjector';
16
16
  export { ProxyInjector } from './injector/ProxyInjector';
17
17
  export { getHooks, hook } from './hook';
18
18
  export { by } from './by';
19
- export { setMetadata, getMetadata } from './metadata';
19
+ export { setMetadata, getMetadata, setParameterMetadata } from './metadata';
@@ -1,16 +1,12 @@
1
- import { constant, merge } from '../utils';
1
+ import { constant, fillEmptyIndexes } from '../utils';
2
+ import { setParameterMetadata } from '../metadata';
2
3
  const INJECT_KEY = 'INJECT_FN_LIST';
3
- export const inject = (value) => (target, propertyKey, parameterIndex) => {
4
- var _a;
5
- const metadata = (_a = Reflect.getOwnMetadata(INJECT_KEY, target)) !== null && _a !== void 0 ? _a : [];
6
- metadata[parameterIndex] = value;
7
- Reflect.defineMetadata(INJECT_KEY, metadata, target);
8
- };
4
+ export const inject = (value) => setParameterMetadata(INJECT_KEY, value);
9
5
  export class ReflectionInjector {
10
6
  resolve(container, Target, ...deps) {
11
7
  var _a;
12
8
  const injectionFns = (_a = Reflect.getOwnMetadata(INJECT_KEY, Target)) !== null && _a !== void 0 ? _a : [];
13
- const args = merge(injectionFns, deps.map(constant)).map((fn) => fn(container));
9
+ const args = fillEmptyIndexes(injectionFns, deps.map(constant)).map((fn) => fn(container));
14
10
  return new Target(...args);
15
11
  }
16
12
  }
package/esm/metadata.js CHANGED
@@ -5,3 +5,9 @@ export const setMetadata = (key, value) => (target) => {
5
5
  export function getMetadata(target, key) {
6
6
  return Reflect.getOwnMetadata(key, target);
7
7
  }
8
+ export const setParameterMetadata = (key, value) => (target, propertyKey, parameterIndex) => {
9
+ var _a;
10
+ const metadata = (_a = Reflect.getOwnMetadata(key, target)) !== null && _a !== void 0 ? _a : [];
11
+ metadata[parameterIndex] = value;
12
+ Reflect.defineMetadata(key, metadata, target);
13
+ };
package/esm/utils.js CHANGED
@@ -1,17 +1,14 @@
1
1
  export function pipe(...mappers) {
2
2
  return (value) => mappers.reduce((acc, current) => current(acc), value);
3
3
  }
4
- export function merge(baseArr, insertArr) {
5
- if (baseArr.length === 0) {
6
- return insertArr;
4
+ export function fillEmptyIndexes(baseArr, insertArr) {
5
+ const a = [...baseArr];
6
+ const b = [...insertArr];
7
+ for (let i = 0; i < a.length; i++) {
8
+ if (a[i] === undefined) {
9
+ a[i] = b.shift();
10
+ }
7
11
  }
8
- if (insertArr.length === 0) {
9
- return baseArr;
10
- }
11
- const [b1, ...restBaseArr] = baseArr;
12
- const [i1, ...restInsertArr] = insertArr;
13
- return b1 === undefined
14
- ? [i1].concat(merge(restBaseArr, restInsertArr))
15
- : [b1].concat(merge(restBaseArr, insertArr));
12
+ return a.concat(b);
16
13
  }
17
14
  export const constant = (value) => () => value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "27.4.0",
3
+ "version": "27.4.2",
4
4
  "description": "Typescript IoC container",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -41,8 +41,8 @@
41
41
  "build:cjm": "rimraf cjm && tsc -p tsconfig.production.json --outDir cjm --module CommonJS",
42
42
  "build:esm": "rimraf esm && tsc -p tsconfig.production.json --outDir esm",
43
43
  "build:types": "rimraf typings && tsc -p tsconfig.production.json --outDir typings --emitDeclarationOnly --declaration",
44
- "build:readme": "ts-node scripts/generateReadme/generateReadme.ts",
45
- "build": "npm run build:cjm && npm run build:esm && npm run build:types && npm run build:readme",
44
+ "generate:docs": "ts-node scripts/generateReadme/generateReadme.ts && git add README.md",
45
+ "build": "npm run build:cjm && npm run build:esm && npm run build:types",
46
46
  "coverage": "coveralls",
47
47
  "watch": "nodemon --watch ./lib --exec npm run build",
48
48
  "test": "jest --coverage"
@@ -60,5 +60,5 @@
60
60
  "ts-node": "^10.9.1",
61
61
  "typescript": "4.4.3"
62
62
  },
63
- "gitHead": "917c4879c7452ab78bb70482479e963e451361a3"
63
+ "gitHead": "f3cf3333af2a2182dcce507a564d30c9cbee2ace"
64
64
  }
@@ -20,7 +20,7 @@ export declare class Container implements IContainer, Tagged {
20
20
  dispose(): void;
21
21
  getInstances(): unknown[];
22
22
  hasTag(tag: Tag): boolean;
23
- use(module: IContainerModule): this;
23
+ use(...modules: IContainerModule[]): this;
24
24
  hasDependency(key: DependencyKey): boolean;
25
25
  /**
26
26
  * @private
@@ -23,7 +23,7 @@ export interface IContainer extends Resolvable {
23
23
  removeScope(child: IContainer): void;
24
24
  getInstances(): unknown[];
25
25
  dispose(): void;
26
- use(module: IContainerModule): this;
26
+ use(...modules: IContainerModule[]): this;
27
27
  hasTag(tag: Tag): boolean;
28
28
  getAllProviders(): Map<DependencyKey, IProvider>;
29
29
  getTokensByProvider(predicate: (provider: IProvider) => boolean): DependencyKey[];
@@ -18,4 +18,4 @@ export { SimpleInjector } from './injector/SimpleInjector';
18
18
  export { ProxyInjector } from './injector/ProxyInjector';
19
19
  export { getHooks, hook } from './hook';
20
20
  export { by, InstancePredicate } from './by';
21
- export { setMetadata, getMetadata } from './metadata';
21
+ export { setMetadata, getMetadata, setParameterMetadata } from './metadata';
@@ -1,2 +1,3 @@
1
1
  export declare const setMetadata: <T>(key: string | symbol, value: T) => ClassDecorator;
2
2
  export declare function getMetadata<T>(target: Object, key: string | symbol): T | undefined;
3
+ export declare const setParameterMetadata: <T>(key: string | symbol, value: T) => ParameterDecorator;
@@ -1,5 +1,5 @@
1
1
  export declare type constructor<T> = new (...args: any[]) => T;
2
2
  export declare type MapFn<T> = (value: T) => T;
3
3
  export declare function pipe<T>(...mappers: MapFn<T>[]): MapFn<T>;
4
- export declare function merge<T>(baseArr: (T | undefined)[], insertArr: T[]): T[];
4
+ export declare function fillEmptyIndexes<T>(baseArr: (T | undefined)[], insertArr: T[]): T[];
5
5
  export declare const constant: <T>(value: T) => () => T;