ts-ioc-container 31.1.2 → 31.1.4

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
@@ -22,26 +22,26 @@
22
22
  - [Setup](#setup)
23
23
  - [Container](#container)
24
24
  - [Basic usage](#basic-usage)
25
- - [Scopes](#scopes)
25
+ - [Scope](#scope) `tags`
26
26
  - [Instances](#instances)
27
- - [Disposing](#disposing)
28
- - [Injectors](#injectors)
29
- - [Metadata injector](#metadata-injector) `@inject`
30
- - [Simple injector](#simple-injector)
31
- - [Proxy injector](#proxy-injector)
32
- - [Providers](#providers)
33
- - [Registration module (Provider + DependencyKey)](#registration-and-providers) `@key`
34
- - [Provider](#provider) `@provider`
35
- - [Singleton provider](#singleton-provider)
36
- - [Scope provider](#scope-provider)
37
- - [Args provider](#args-provider)
38
- - [Aliases](#aliases) `alias`
39
- - [Container modules](#container-modules)
40
- - [Hooks](#hooks) `@hook`
27
+ - [Dispose](#dispose)
28
+ - [Injector](#injector)
29
+ - [Metadata](#metadata) `@inject`
30
+ - [Simple](#simple)
31
+ - [Proxy](#proxy)
32
+ - [Visibility](#visibility) `visible`
33
+ - [Provider](#provider) `@provider`
34
+ - [Singleton](#singleton) `singleton`
35
+ - [Arguments](#arguments) `args`
36
+ - [Registration](#registration) `@registration`
37
+ - [Scope](#scope) `scope`
38
+ - [Alias](#alias) `alias`
39
+ - [Module](#module)
40
+ - [Hook](#hook) `@hook`
41
41
  - [OnConstruct](#onconstruct) `@onConstruct`
42
42
  - [OnDispose](#ondispose) `@onDispose`
43
- - [Tests and Mocks](#tests-and-mocks)
44
- - [Errors](#errors)
43
+ - [Mock](#mock)
44
+ - [Error](#error)
45
45
 
46
46
  ## Setup
47
47
 
@@ -68,10 +68,11 @@ And `tsconfig.json` should have next options:
68
68
  ```
69
69
 
70
70
  ## Container
71
- `IContainer` consists of 2 main parts:
71
+ `IContainer` consists of:
72
72
 
73
- - Providers - describes how to create instances of dependencies
74
- - Injector - describes how to inject dependencies to constructor
73
+ - Provider is dependency factory which creates dependency
74
+ - Injector describes how to inject dependencies to constructor
75
+ - Registration is provider factory which registers provider in container
75
76
 
76
77
  ### Basic usage
77
78
 
@@ -89,7 +90,7 @@ describe('Basic usage', function () {
89
90
  constructor(@inject(by.key('ILogger')) public logger: Logger) {}
90
91
  }
91
92
 
92
- const container = new Container(new MetadataInjector()).addRegistration(R.fromClass(Logger).to('ILogger'));
93
+ const container = new Container(new MetadataInjector()).add(R.fromClass(Logger).to('ILogger'));
93
94
 
94
95
  expect(container.resolve(App).logger.name).toBe('Logger');
95
96
  });
@@ -100,8 +101,8 @@ describe('Basic usage', function () {
100
101
  }
101
102
 
102
103
  const container = new Container(new MetadataInjector())
103
- .addRegistration(R.fromClass(Logger).to('ILogger1'))
104
- .addRegistration(R.fromClass(Logger).to('ILogger2'));
104
+ .add(R.fromClass(Logger).to('ILogger1'))
105
+ .add(R.fromClass(Logger).to('ILogger2'));
105
106
 
106
107
  expect(container.resolve(App).loggers).toHaveLength(2);
107
108
  });
@@ -121,7 +122,7 @@ describe('Basic usage', function () {
121
122
 
122
123
  ```
123
124
 
124
- ### Scopes
125
+ ### Scope
125
126
  Sometimes you need to create a scope of container. For example, when you want to create a scope per request in web application. You can assign tags to scope and provider and resolve dependencies only from certain scope.
126
127
 
127
128
  - NOTICE: remember that when scope doesn't have dependency then it will be resolved from parent container
@@ -151,7 +152,7 @@ class Logger {}
151
152
 
152
153
  describe('Scopes', function () {
153
154
  it('should resolve dependencies from scope', function () {
154
- const root = new Container(new MetadataInjector(), { tags: ['root'] }).addRegistration(R.fromClass(Logger));
155
+ const root = new Container(new MetadataInjector(), { tags: ['root'] }).add(R.fromClass(Logger));
155
156
  const child = root.createScope('child');
156
157
 
157
158
  expect(child.resolve('ILogger')).toBe(child.resolve('ILogger'));
@@ -188,7 +189,7 @@ describe('Instances', function () {
188
189
  class Logger {}
189
190
 
190
191
  it('should return injected instances', () => {
191
- const container = new Container(new MetadataInjector()).addRegistration(R.fromClass(Logger));
192
+ const container = new Container(new MetadataInjector()).add(R.fromClass(Logger));
192
193
  const scope = container.createScope();
193
194
 
194
195
  const logger1 = container.resolve('ILogger');
@@ -205,7 +206,7 @@ describe('Instances', function () {
205
206
  constructor(@inject(by.instances(isLogger)) public loggers: Logger[]) {}
206
207
  }
207
208
 
208
- const container = new Container(new MetadataInjector()).addRegistration(R.fromClass(Logger));
209
+ const container = new Container(new MetadataInjector()).add(R.fromClass(Logger));
209
210
 
210
211
  const logger0 = container.resolve('ILogger');
211
212
  const logger1 = container.resolve('ILogger');
@@ -219,7 +220,7 @@ describe('Instances', function () {
219
220
 
220
221
  ```
221
222
 
222
- ### Disposing
223
+ ### Dispose
223
224
  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.
224
225
 
225
226
  - container can be disposed
@@ -234,9 +235,7 @@ class Logger {}
234
235
 
235
236
  describe('Disposing', function () {
236
237
  it('should container and make it unavailable for the further usage', function () {
237
- const root = new Container(new MetadataInjector(), { tags: ['root'] }).addRegistration(
238
- R.fromClass(Logger).to('ILogger'),
239
- );
238
+ const root = new Container(new MetadataInjector(), { tags: ['root'] }).add(R.fromClass(Logger).to('ILogger'));
240
239
  const child = root.createScope('child');
241
240
 
242
241
  const logger = child.resolve('ILogger');
@@ -250,14 +249,14 @@ describe('Disposing', function () {
250
249
 
251
250
  ```
252
251
 
253
- ## Injectors
252
+ ## Injector
254
253
  `IInjector` is used to describe how dependencies should be injected to constructor.
255
254
 
256
255
  - `MetadataInjector` - injects dependencies using `@inject` decorator
257
256
  - `ProxyInjector` - injects dependencies as dictionary `Record<string, unknown>`
258
257
  - `SimpleInjector` - just passes container to constructor with others arguments
259
258
 
260
- ### Metadata injector
259
+ ### Metadata
261
260
  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 `MetadataInjector`.
262
261
 
263
262
  ```typescript
@@ -282,7 +281,7 @@ class App {
282
281
 
283
282
  describe('Reflection Injector', function () {
284
283
  it('should inject dependencies by @inject decorator', function () {
285
- const container = new Container(new MetadataInjector()).addRegistration(R.fromClass(Logger).to('ILogger'));
284
+ const container = new Container(new MetadataInjector()).add(R.fromClass(Logger).to('ILogger'));
286
285
 
287
286
  const app = container.resolve(App);
288
287
 
@@ -292,7 +291,7 @@ describe('Reflection Injector', function () {
292
291
 
293
292
  ```
294
293
 
295
- ### Simple injector
294
+ ### Simple
296
295
  This type of injector just passes container to constructor with others arguments.
297
296
 
298
297
  ```typescript
@@ -305,7 +304,7 @@ describe('SimpleInjector', function () {
305
304
  constructor(public container: IContainer) {}
306
305
  }
307
306
 
308
- const container = new Container(new SimpleInjector()).addRegistration(R.fromClass(App).to('App'));
307
+ const container = new Container(new SimpleInjector()).add(R.fromClass(App).to('App'));
309
308
  const app = container.resolve<App>('App');
310
309
 
311
310
  expect(app.container).toBeInstanceOf(Container);
@@ -319,7 +318,7 @@ describe('SimpleInjector', function () {
319
318
  ) {}
320
319
  }
321
320
 
322
- const container = new Container(new SimpleInjector()).addRegistration(R.fromClass(App).to('App'));
321
+ const container = new Container(new SimpleInjector()).add(R.fromClass(App).to('App'));
323
322
  const app = container.resolve<App>('App', { args: ['Hello world'] });
324
323
 
325
324
  expect(app.greeting).toBe('Hello world');
@@ -328,7 +327,7 @@ describe('SimpleInjector', function () {
328
327
 
329
328
  ```
330
329
 
331
- ### Proxy injector
330
+ ### Proxy
332
331
  This type of injector injects dependencies as dictionary `Record<string, unknown>`.
333
332
 
334
333
  ```typescript
@@ -347,7 +346,7 @@ describe('ProxyInjector', function () {
347
346
  }
348
347
  }
349
348
 
350
- const container = new Container(new ProxyInjector()).addRegistration(R.fromClass(Logger).to('logger'));
349
+ const container = new Container(new ProxyInjector()).add(R.fromClass(Logger).to('logger'));
351
350
 
352
351
  const app = container.resolve(App);
353
352
  expect(app.logger).toBeInstanceOf(Logger);
@@ -377,8 +376,8 @@ describe('ProxyInjector', function () {
377
376
  const greetingTemplate = (name: string) => `Hello ${name}`;
378
377
 
379
378
  const container = new Container(new ProxyInjector())
380
- .addRegistration(R.fromClass(App).to('App').pipe(args({ greetingTemplate })))
381
- .addRegistration(R.fromClass(Logger).to('logger'));
379
+ .add(R.fromClass(App).to('App').pipe(args({ greetingTemplate })))
380
+ .add(R.fromClass(Logger).to('logger'));
382
381
 
383
382
  const app = container.resolve<App>('App', { args: [{ name: `world` }] });
384
383
  expect(app.greeting).toBe('Hello world');
@@ -387,71 +386,13 @@ describe('ProxyInjector', function () {
387
386
 
388
387
  ```
389
388
 
390
- ## Registration and Providers
391
- `IProvider<T>` is used to describe how instances should be created. It has next basic methods:
392
- - `resolve` - creates instance with passed arguments
393
- - `clone` - we invoke it when we create a scope. It clones provider to new scope.
394
- - `isValid` - checks if provider can be resolved from container or cloned to container with certain tags
395
-
396
- There are next types of providers:
397
- - `Provider` - basic provider. It can be used with `@provider` decorator
398
- - `SingletonProvider` - provider that creates only one instance in every scope where it's resolved
399
- - `ScopeProvider` - provider that can be resolved only from container with certain tags and their sub scopes
400
- - `ArgsProvider` - provider that encapsulates arguments to pass it to constructor.
401
-
402
- `Registration` - just a helper to register provider with certain key. `(preferrably to use)`
389
+ ## Provider
390
+ Provider is dependency factory which creates dependency.
403
391
 
404
- ### Registration (Provider + DependencyKey)
405
- 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.
406
-
407
- ```typescript
408
- import 'reflect-metadata';
409
- import { Container, key, MetadataInjector, provider, register, Registration as R, scope, singleton } from 'ts-ioc-container';
410
- import { DependencyMissingKeyError } from '../../lib/errors/DependencyMissingKeyError';
411
-
412
- describe('Registration module', function () {
413
- const createContainer = () => new Container(new MetadataInjector(), { tags: ['root'] });
414
-
415
- it('should register class', function () {
416
- @register(key('ILogger'), scope((s) => s.hasTag('root')))
417
- @provider(singleton())
418
- class Logger {}
419
-
420
- const root = createContainer().addRegistration(R.fromClass(Logger));
421
-
422
- expect(root.resolve('ILogger')).toBeInstanceOf(Logger);
423
- });
424
-
425
- it('should register value', function () {
426
- const root = createContainer().addRegistration(R.fromValue('smth').to('ISmth'));
427
-
428
- expect(root.resolve('ISmth')).toBe('smth');
429
- });
430
-
431
- it('should register fn', function () {
432
- const root = createContainer().addRegistration(R.fromFn(() => 'smth').to('ISmth'));
433
-
434
- expect(root.resolve('ISmth')).toBe('smth');
435
- });
436
-
437
- it('should raise an error if key is not provider', () => {
438
- expect(() => {
439
- createContainer().addRegistration(R.fromValue('smth'));
440
- }).toThrowError(DependencyMissingKeyError);
441
- });
442
-
443
- it('should register dependency by class name if @key is not provided', function () {
444
- class FileLogger {}
445
-
446
- const root = createContainer().addRegistration(R.fromClass(FileLogger));
447
-
448
- expect(root.resolve('FileLogger')).toBeInstanceOf(FileLogger);
449
- });
450
- });
451
-
452
- ```
453
-
454
- ### Provider
392
+ - `@provider()`
393
+ - `Provider.fromClass(Logger)`
394
+ - `Provider.fromValue(logger)`
395
+ - `new Provider((container, ...args) => container.resolve(Logger, {args}))`
455
396
 
456
397
  ```typescript
457
398
  import 'reflect-metadata';
@@ -490,7 +431,7 @@ describe('Provider', function () {
490
431
 
491
432
  ```
492
433
 
493
- ### Singleton provider
434
+ ### Singleton
494
435
  Sometimes you need to create only one instance of dependency per scope. For example, you want to create only one logger per scope.
495
436
 
496
437
  - Singleton provider creates only one instance in every scope where it's resolved.
@@ -510,20 +451,20 @@ describe('Singleton', function () {
510
451
  }
511
452
 
512
453
  it('should resolve the same container per every request', function () {
513
- const container = createContainer().addRegistration(R.fromClass(Logger));
454
+ const container = createContainer().add(R.fromClass(Logger));
514
455
 
515
456
  expect(container.resolve('logger')).toBe(container.resolve('logger'));
516
457
  });
517
458
 
518
459
  it('should resolve different dependency per scope', function () {
519
- const container = createContainer().addRegistration(R.fromClass(Logger));
460
+ const container = createContainer().add(R.fromClass(Logger));
520
461
  const child = container.createScope();
521
462
 
522
463
  expect(container.resolve('logger')).not.toBe(child.resolve('logger'));
523
464
  });
524
465
 
525
466
  it('should resolve the same dependency for scope', function () {
526
- const container = createContainer().addRegistration(R.fromClass(Logger));
467
+ const container = createContainer().add(R.fromClass(Logger));
527
468
  const child = container.createScope();
528
469
 
529
470
  expect(child.resolve('logger')).toBe(child.resolve('logger'));
@@ -532,29 +473,11 @@ describe('Singleton', function () {
532
473
 
533
474
  ```
534
475
 
535
- ### Scope provider
536
- Sometimes you need to resolve provider only from scope which matches to certain condition and their sub scopes. Especially if you want to register dependency as singleton for some tags, for example `root`
537
- - NOTICE: It doesn't make clones in not predicate-matched scopes. Usually it's used with `SingletonProvider`.
538
-
539
- ```typescript
540
- import 'reflect-metadata';
541
- import { singleton, Container, key, provider, MetadataInjector, Registration as R, scope, register } from 'ts-ioc-container';
542
-
543
- @register(key('ILogger'), scope((s) => s.hasTag('root')))
544
- @provider(singleton()) // the same as .pipe(singleton(), scope((s) => s.hasTag('root')))
545
- class Logger {}
546
- describe('ScopeProvider', function () {
547
- it('should return the same instance', function () {
548
- const root = new Container(new MetadataInjector(), { tags: ['root'] }).addRegistration(R.fromClass(Logger));
549
- const child = root.createScope();
550
- expect(root.resolve('ILogger')).toBe(child.resolve('ILogger'));
551
- });
552
- });
553
-
554
- ```
555
-
556
- ### Args provider
476
+ ### Arguments
557
477
  Sometimes you want to bind some arguments to provider. This is what `ArgsProvider` is for.
478
+ - `@provider(args('someArgument'))`
479
+ - `@provider(argsFn((container) => [container.resolve(Logger), 'someValue']))`
480
+ - `Provider.fromClass(Logger).pipe(args('someArgument'))`
558
481
  - NOTICE: args from this provider has higher priority than args from `resolve` method.
559
482
 
560
483
  ```typescript
@@ -575,21 +498,21 @@ describe('ArgsProvider', function () {
575
498
  }
576
499
 
577
500
  it('can assign argument function to provider', function () {
578
- const root = createContainer().addRegistration(R.fromClass(Logger).pipe(argsFn((container, ...args) => ['name'])));
501
+ const root = createContainer().add(R.fromClass(Logger).pipe(argsFn((container, ...args) => ['name'])));
579
502
 
580
503
  const logger = root.createScope().resolve<Logger>('logger');
581
504
  expect(logger.name).toBe('name');
582
505
  });
583
506
 
584
507
  it('can assign argument to provider', function () {
585
- const root = createContainer().addRegistration(R.fromClass(Logger).pipe(args('name')));
508
+ const root = createContainer().add(R.fromClass(Logger).pipe(args('name')));
586
509
 
587
510
  const logger = root.resolve<Logger>('logger');
588
511
  expect(logger.name).toBe('name');
589
512
  });
590
513
 
591
514
  it('should set provider arguments with highest priority in compare to resolve arguments', function () {
592
- const root = createContainer().addRegistration(R.fromClass(Logger).pipe(args('name')));
515
+ const root = createContainer().add(R.fromClass(Logger).pipe(args('name')));
593
516
 
594
517
  const logger = root.resolve<Logger>('logger', { args: ['file'] });
595
518
 
@@ -600,11 +523,125 @@ describe('ArgsProvider', function () {
600
523
 
601
524
  ```
602
525
 
603
- ### Aliases
604
- Sometimes you want to register the same provider with different keys. This is what `Aliases` is for.
605
- - `@provider(alias('logger'))` helper assigns `logger` alias to provider.
606
- - `by.alias.some('logger', 'a')` method resolves the same provider with different keys. (logger OR a)
607
- - `by.alias.all('logger', 'a')` method resolves to resolve the same provider with different keys. (logger AND a)
526
+ ### Visibility
527
+ Sometimes you want to hide dependency if somebody wants to resolve it from certain scope
528
+ - `@provider(visible(({ isParent, child }) => isParent || child.hasTag('root')))` - dependency will be accessible from scope `root` or from scope where it's registered
529
+ - `Provider.fromClass(Logger).pipe(visible(({ isParent, child }) => isParent || child.hasTag('root')))`
530
+
531
+ ```typescript
532
+ import 'reflect-metadata';
533
+ import {
534
+ Container,
535
+ DependencyNotFoundError,
536
+ key,
537
+ MetadataInjector,
538
+ provider,
539
+ register,
540
+ Registration as R,
541
+ scope,
542
+ singleton,
543
+ visible,
544
+ } from 'ts-ioc-container';
545
+
546
+ describe('Visibility', function () {
547
+ it('should hide from children', () => {
548
+ @register(key('logger'), scope((s) => s.hasTag('root')))
549
+ @provider(singleton(), visible(({ isParent }) => isParent))
550
+ class FileLogger {}
551
+
552
+ const parent = new Container(new MetadataInjector(), { tags: ['root'] }).add(R.fromClass(FileLogger));
553
+
554
+ const child = parent.createScope('child');
555
+
556
+ expect(() => child.resolve('logger')).toThrowError(DependencyNotFoundError);
557
+ expect(parent.resolve('logger')).toBeInstanceOf(FileLogger);
558
+ });
559
+ });
560
+
561
+ ```
562
+
563
+ ## Registration
564
+ Registration is provider factory which registers provider in container.
565
+ - `@registration(key('logger'))`
566
+ - `Registration.fromClass(Logger).to('logger')`
567
+ - `Registration.fromClass(Logger)`
568
+ - `Registration.fromValue(Logger)`
569
+ - `Registration.fromFn((container, ...args) => container.resolve(Logger, {args}))`
570
+
571
+ ```typescript
572
+ import 'reflect-metadata';
573
+ import { Container, key, MetadataInjector, provider, register, Registration as R, scope, singleton } from 'ts-ioc-container';
574
+ import { DependencyMissingKeyError } from '../../lib/errors/DependencyMissingKeyError';
575
+
576
+ describe('Registration module', function () {
577
+ const createContainer = () => new Container(new MetadataInjector(), { tags: ['root'] });
578
+
579
+ it('should register class', function () {
580
+ @register(key('ILogger'), scope((s) => s.hasTag('root')))
581
+ @provider(singleton())
582
+ class Logger {}
583
+
584
+ const root = createContainer().add(R.fromClass(Logger));
585
+
586
+ expect(root.resolve('ILogger')).toBeInstanceOf(Logger);
587
+ });
588
+
589
+ it('should register value', function () {
590
+ const root = createContainer().add(R.fromValue('smth').to('ISmth'));
591
+
592
+ expect(root.resolve('ISmth')).toBe('smth');
593
+ });
594
+
595
+ it('should register fn', function () {
596
+ const root = createContainer().add(R.fromFn(() => 'smth').to('ISmth'));
597
+
598
+ expect(root.resolve('ISmth')).toBe('smth');
599
+ });
600
+
601
+ it('should raise an error if key is not provider', () => {
602
+ expect(() => {
603
+ createContainer().add(R.fromValue('smth'));
604
+ }).toThrowError(DependencyMissingKeyError);
605
+ });
606
+
607
+ it('should register dependency by class name if @key is not provided', function () {
608
+ class FileLogger {}
609
+
610
+ const root = createContainer().add(R.fromClass(FileLogger));
611
+
612
+ expect(root.resolve('FileLogger')).toBeInstanceOf(FileLogger);
613
+ });
614
+ });
615
+
616
+ ```
617
+
618
+ ### Scope
619
+ Sometimes you need to register provider only in scope which matches to certain condition and their sub scopes. Especially if you want to register dependency as singleton for some tags, for example `root`
620
+ - `@registration(scope((container) => container.hasTag('root'))` - register provider only in root scope
621
+ - `Registration.fromClass(Logger).when((container) => container.hasTag('root'))`
622
+
623
+ ```typescript
624
+ import 'reflect-metadata';
625
+ import { singleton, Container, key, provider, MetadataInjector, Registration as R, scope, register } from 'ts-ioc-container';
626
+
627
+ @register(key('ILogger'), scope((s) => s.hasTag('root')))
628
+ @provider(singleton()) // the same as .pipe(singleton(), scope((s) => s.hasTag('root')))
629
+ class Logger {}
630
+ describe('ScopeProvider', function () {
631
+ it('should return the same instance', function () {
632
+ const root = new Container(new MetadataInjector(), { tags: ['root'] }).add(R.fromClass(Logger));
633
+ const child = root.createScope();
634
+ expect(root.resolve('ILogger')).toBe(child.resolve('ILogger'));
635
+ });
636
+ });
637
+
638
+ ```
639
+
640
+ ### Alias
641
+ Alias is needed to group keys
642
+ - `@registration(alias('logger'))` helper assigns `logger` alias to registration.
643
+ - `by.aliases((it) => it.has('logger') || it.has('a'))` resolves dependencies which have `logger` or `a` aliases
644
+ - `Registration.fromClass(Logger).addAliases('logger')`
608
645
 
609
646
  ```typescript
610
647
  import 'reflect-metadata';
@@ -649,7 +686,7 @@ describe('alias', () => {
649
686
  it('should resolve by some alias', () => {
650
687
  class App implements IApplication {
651
688
  private appliedMiddleware: Set<string> = new Set();
652
- constructor(@inject(by.aliases((it) => it.includes(IMiddlewareKey))) public middleware: IMiddleware[]) {}
689
+ constructor(@inject(by.aliases((it) => it.has(IMiddlewareKey))) public middleware: IMiddleware[]) {}
653
690
 
654
691
  markMiddlewareAsApplied(name: string): void {
655
692
  this.appliedMiddleware.add(name);
@@ -671,8 +708,8 @@ describe('alias', () => {
671
708
  }
672
709
 
673
710
  const container = new Container(new MetadataInjector())
674
- .addRegistration(R.fromClass(LoggerMiddleware))
675
- .addRegistration(R.fromClass(ErrorHandlerMiddleware));
711
+ .add(R.fromClass(LoggerMiddleware))
712
+ .add(R.fromClass(ErrorHandlerMiddleware));
676
713
 
677
714
  const app = container.resolve(App);
678
715
  app.run();
@@ -685,16 +722,17 @@ describe('alias', () => {
685
722
  @register(alias('ILogger'))
686
723
  class FileLogger {}
687
724
 
688
- const container = new Container(new MetadataInjector()).addRegistration(R.fromClass(FileLogger));
725
+ const container = new Container(new MetadataInjector()).add(R.fromClass(FileLogger));
689
726
 
690
- expect(by.alias((aliases) => aliases.includes('ILogger'))(container)).toBeInstanceOf(FileLogger);
691
- expect(() => by.alias((aliases) => aliases.includes('logger'))(container)).toThrowError(DependencyNotFoundError);
727
+ expect(by.alias((aliases) => aliases.has('ILogger'))(container)).toBeInstanceOf(FileLogger);
728
+ expect(() => by.alias((aliases) => aliases.has('logger'))(container)).toThrowError(DependencyNotFoundError);
692
729
  });
693
730
  });
694
731
 
695
732
  ```
696
733
 
697
- ## Container modules
734
+
735
+ ## Module
698
736
  Sometimes you want to encapsulate registration logic in separate module. This is what `IContainerModule` is for.
699
737
 
700
738
  ```typescript
@@ -709,13 +747,13 @@ class TestLogger {}
709
747
 
710
748
  class Production implements IContainerModule {
711
749
  applyTo(container: IContainer): void {
712
- container.addRegistration(R.fromClass(Logger));
750
+ container.add(R.fromClass(Logger));
713
751
  }
714
752
  }
715
753
 
716
754
  class Development implements IContainerModule {
717
755
  applyTo(container: IContainer): void {
718
- container.addRegistration(R.fromClass(TestLogger));
756
+ container.add(R.fromClass(TestLogger));
719
757
  }
720
758
  }
721
759
 
@@ -739,7 +777,7 @@ describe('Container Modules', function () {
739
777
 
740
778
  ```
741
779
 
742
- ## Hooks
780
+ ## Hook
743
781
  Sometimes you need to invoke methods after construct or dispose of class. This is what hooks are for.
744
782
 
745
783
  ### OnConstruct
@@ -764,7 +802,7 @@ class MyInjector implements IInjector {
764
802
  resolve<T>(container: IContainer, value: constructor<T>, ...deps: unknown[]): T {
765
803
  const instance = this.injector.resolve(container, value, ...deps);
766
804
  // eslint-disable-next-line @typescript-eslint/ban-types
767
- for (const h of getHooks(instance as object, 'onConstruct')) {
805
+ for (const [h] of getHooks(instance as object, 'onConstruct')) {
768
806
  // @ts-ignore
769
807
  instance[h]();
770
808
  }
@@ -788,7 +826,7 @@ class Logger {
788
826
 
789
827
  describe('onConstruct', function () {
790
828
  it('should make logger be ready on resolve', function () {
791
- const container = new Container(new MyInjector()).addRegistration(R.fromClass(Logger));
829
+ const container = new Container(new MyInjector()).add(R.fromClass(Logger));
792
830
 
793
831
  const logger = container.resolve<Logger>('logger');
794
832
 
@@ -814,6 +852,7 @@ import {
814
852
  MetadataInjector,
815
853
  register,
816
854
  } from 'ts-ioc-container';
855
+ import * as console from 'node:console';
817
856
 
818
857
  @register(key('logsRepo'))
819
858
  @provider(singleton())
@@ -844,16 +883,14 @@ class Logger {
844
883
 
845
884
  describe('onDispose', function () {
846
885
  it('should invoke hooks on all instances', async function () {
847
- const container = new Container(new MetadataInjector())
848
- .addRegistration(R.fromClass(Logger))
849
- .addRegistration(R.fromClass(LogsRepo));
886
+ const container = new Container(new MetadataInjector()).add(R.fromClass(Logger)).add(R.fromClass(LogsRepo));
850
887
 
851
888
  const logger = container.resolve<Logger>('logger');
852
889
  logger.log('Hello');
853
890
 
854
891
  for (const instance of container.getInstances()) {
855
892
  // eslint-disable-next-line @typescript-eslint/ban-types
856
- for (const h of getHooks(instance as object, 'onDispose')) {
893
+ for (const [h] of getHooks(instance as object, 'onDispose')) {
857
894
  // @ts-ignore
858
895
  await instance[h]();
859
896
  }
@@ -865,7 +902,7 @@ describe('onDispose', function () {
865
902
 
866
903
  ```
867
904
 
868
- ## Tests and Mocks
905
+ ## Mock
869
906
  Sometimes you need to automatically mock all dependencies in container. This is what `AutoMockedContainer` is for.
870
907
 
871
908
  ```typescript
@@ -907,9 +944,10 @@ describe('Mocking', () => {
907
944
 
908
945
  ```
909
946
 
910
- ## Errors
947
+ ## Error
911
948
 
912
- - [DependencyNotFoundError.ts](lib%2Fcontainer%2FDependencyNotFoundError.ts)
913
- - [MethodNotImplementedError.ts](lib%2FMethodNotImplementedError.ts)
914
- - [ContainerDisposedError.ts](lib%2Fcontainer%2FContainerDisposedError.ts)
949
+ - [DependencyNotFoundError.ts](..%2F..%2Flib%2Ferrors%2FDependencyNotFoundError.ts)
950
+ - [MethodNotImplementedError.ts](..%2F..%2Flib%2Ferrors%2FMethodNotImplementedError.ts)
951
+ - [DependencyMissingKeyError.ts](..%2F..%2Flib%2Ferrors%2FDependencyMissingKeyError.ts)
952
+ - [ContainerDisposedError.ts](..%2F..%2Flib%2Ferrors%2FContainerDisposedError.ts)
915
953
 
@@ -32,7 +32,7 @@ class AutoMockedContainer {
32
32
  hasTag() {
33
33
  return false;
34
34
  }
35
- addRegistration(registration) {
35
+ add(registration) {
36
36
  return this;
37
37
  }
38
38
  getKeyByAlias(alias) {
@@ -16,7 +16,7 @@ class Container {
16
16
  this.parent = options.parent ?? new EmptyContainer_1.EmptyContainer();
17
17
  this.tags = new Set(options.tags ?? []);
18
18
  }
19
- addRegistration(registration) {
19
+ add(registration) {
20
20
  this.registrations.push(registration);
21
21
  registration.applyTo(this);
22
22
  return this;
@@ -25,7 +25,7 @@ class Container {
25
25
  this.validateContainer();
26
26
  this.providers.set(key, provider);
27
27
  if (aliases && aliases.length > 0) {
28
- this.aliases.set(key, aliases);
28
+ this.aliases.set(key, new Set(aliases));
29
29
  }
30
30
  return this;
31
31
  }
@@ -70,10 +70,8 @@ class Container {
70
70
  hasTag(tag) {
71
71
  return this.tags.has(tag);
72
72
  }
73
- use(...modules) {
74
- for (const module of modules) {
75
- module.applyTo(this);
76
- }
73
+ use(module) {
74
+ module.applyTo(this);
77
75
  return this;
78
76
  }
79
77
  hasDependency(key) {
@@ -108,9 +106,8 @@ class Container {
108
106
  * @private
109
107
  */
110
108
  getRegistrations() {
111
- return this.registrations.length
112
- ? this.parent.getRegistrations().concat(this.registrations)
113
- : this.parent.getRegistrations();
109
+ const registrations = this.parent.getRegistrations();
110
+ return this.registrations.length > 0 ? registrations.concat(this.registrations) : registrations;
114
111
  }
115
112
  /**
116
113
  * @private
@@ -38,7 +38,7 @@ class EmptyContainer {
38
38
  use(module) {
39
39
  throw new MethodNotImplementedError_1.MethodNotImplementedError();
40
40
  }
41
- addRegistration(registration) {
41
+ add(registration) {
42
42
  return this;
43
43
  }
44
44
  getKeyByAlias(alias) {
package/cjm/hook.js CHANGED
@@ -1,13 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getHooks = exports.hook = void 0;
4
- const hook = (key) => (target, propertyKey) => {
5
- const hooks = Reflect.hasMetadata(key, target.constructor) ? Reflect.getMetadata(key, target.constructor) : [];
6
- Reflect.defineMetadata(key, [...hooks, propertyKey], target.constructor); // eslint-disable-line @typescript-eslint/ban-types
3
+ exports.hasHooks = exports.getHooks = exports.hook = void 0;
4
+ const hook = (key, fn = () => []) => (target, propertyKey) => {
5
+ const hooks = Reflect.hasMetadata(key, target.constructor)
6
+ ? Reflect.getMetadata(key, target.constructor)
7
+ : new Map();
8
+ hooks.set(propertyKey, fn);
9
+ Reflect.defineMetadata(key, hooks, target.constructor); // eslint-disable-line @typescript-eslint/ban-types
7
10
  };
8
11
  exports.hook = hook;
9
- // eslint-disable-next-line @typescript-eslint/ban-types
10
12
  function getHooks(target, key) {
11
- return Reflect.hasMetadata(key, target.constructor) ? Reflect.getMetadata(key, target.constructor) : [];
13
+ return Reflect.hasMetadata(key, target.constructor) ? Reflect.getMetadata(key, target.constructor) : new Map();
12
14
  }
13
15
  exports.getHooks = getHooks;
16
+ function hasHooks(target, key) {
17
+ return Reflect.hasMetadata(key, target.constructor);
18
+ }
19
+ exports.hasHooks = hasHooks;
package/cjm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.by = exports.hook = exports.getHooks = exports.ProxyInjector = exports.SimpleInjector = exports.inject = exports.MetadataInjector = exports.register = exports.scope = exports.alias = exports.key = exports.Registration = exports.AutoMockedContainer = exports.SingletonProvider = exports.singleton = exports.ArgsProvider = exports.args = exports.argsFn = exports.ProviderDecorator = exports.Provider = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.visible = exports.provider = exports.EmptyContainer = exports.Container = exports.isDependencyKey = void 0;
3
+ exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.by = exports.hasHooks = exports.hook = exports.getHooks = exports.ProxyInjector = exports.SimpleInjector = exports.inject = exports.MetadataInjector = exports.register = exports.scope = exports.alias = exports.key = exports.Registration = exports.AutoMockedContainer = exports.SingletonProvider = exports.singleton = exports.ArgsProvider = exports.args = exports.argsFn = exports.ProviderDecorator = exports.Provider = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.visible = exports.provider = 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");
@@ -46,9 +46,13 @@ Object.defineProperty(exports, "ProxyInjector", { enumerable: true, get: functio
46
46
  var hook_1 = require("./hook");
47
47
  Object.defineProperty(exports, "getHooks", { enumerable: true, get: function () { return hook_1.getHooks; } });
48
48
  Object.defineProperty(exports, "hook", { enumerable: true, get: function () { return hook_1.hook; } });
49
+ Object.defineProperty(exports, "hasHooks", { enumerable: true, get: function () { return hook_1.hasHooks; } });
49
50
  var by_1 = require("./by");
50
51
  Object.defineProperty(exports, "by", { enumerable: true, get: function () { return by_1.by; } });
51
52
  var metadata_1 = require("./metadata");
52
53
  Object.defineProperty(exports, "setMetadata", { enumerable: true, get: function () { return metadata_1.setMetadata; } });
53
54
  Object.defineProperty(exports, "getMetadata", { enumerable: true, get: function () { return metadata_1.getMetadata; } });
54
55
  Object.defineProperty(exports, "setParameterMetadata", { enumerable: true, get: function () { return metadata_1.setParameterMetadata; } });
56
+ Object.defineProperty(exports, "setMethodMetadata", { enumerable: true, get: function () { return metadata_1.setMethodMetadata; } });
57
+ Object.defineProperty(exports, "getMethodMetadata", { enumerable: true, get: function () { return metadata_1.getMethodMetadata; } });
58
+ Object.defineProperty(exports, "getParameterMetadata", { enumerable: true, get: function () { return metadata_1.getParameterMetadata; } });
package/cjm/metadata.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getParameterMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = void 0;
3
+ exports.getMethodMetadata = exports.setMethodMetadata = exports.getParameterMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = void 0;
4
4
  const setMetadata = (key, value) => (target) => {
5
5
  Reflect.defineMetadata(key, value, target);
6
6
  };
@@ -19,3 +19,9 @@ const getParameterMetadata = (key, target) => {
19
19
  return Reflect.getOwnMetadata(key, target) ?? [];
20
20
  };
21
21
  exports.getParameterMetadata = getParameterMetadata;
22
+ const setMethodMetadata = (key, value) => (target, propertyKey) => {
23
+ Reflect.defineMetadata(key, value, target.constructor, propertyKey);
24
+ };
25
+ exports.setMethodMetadata = setMethodMetadata;
26
+ const getMethodMetadata = (key, target, propertyKey) => Reflect.getMetadata(key, target.constructor, propertyKey);
27
+ exports.getMethodMetadata = getMethodMetadata;
@@ -6,7 +6,7 @@ const key = (key) => (r) => r.to(key);
6
6
  exports.key = key;
7
7
  const alias = (...aliases) => (r) => r.addAliases(...aliases);
8
8
  exports.alias = alias;
9
- const scope = (predicate) => (r) => r.setScopePredicate(predicate);
9
+ const scope = (predicate) => (r) => r.when(predicate);
10
10
  exports.scope = scope;
11
11
  const METADATA_KEY = 'registration';
12
12
  const getTransformers = (Target) => (0, metadata_1.getMetadata)(Target, METADATA_KEY) ?? [];
@@ -50,7 +50,7 @@ class Registration {
50
50
  }
51
51
  container.register(this.key, this.createProvider(), this.aliases);
52
52
  }
53
- setScopePredicate(isValidWhen) {
53
+ when(isValidWhen) {
54
54
  this.matchScope = isValidWhen;
55
55
  return this;
56
56
  }
@@ -29,7 +29,7 @@ export class AutoMockedContainer {
29
29
  hasTag() {
30
30
  return false;
31
31
  }
32
- addRegistration(registration) {
32
+ add(registration) {
33
33
  return this;
34
34
  }
35
35
  getKeyByAlias(alias) {
@@ -13,7 +13,7 @@ export class Container {
13
13
  this.parent = options.parent ?? new EmptyContainer();
14
14
  this.tags = new Set(options.tags ?? []);
15
15
  }
16
- addRegistration(registration) {
16
+ add(registration) {
17
17
  this.registrations.push(registration);
18
18
  registration.applyTo(this);
19
19
  return this;
@@ -22,7 +22,7 @@ export class Container {
22
22
  this.validateContainer();
23
23
  this.providers.set(key, provider);
24
24
  if (aliases && aliases.length > 0) {
25
- this.aliases.set(key, aliases);
25
+ this.aliases.set(key, new Set(aliases));
26
26
  }
27
27
  return this;
28
28
  }
@@ -67,10 +67,8 @@ export class Container {
67
67
  hasTag(tag) {
68
68
  return this.tags.has(tag);
69
69
  }
70
- use(...modules) {
71
- for (const module of modules) {
72
- module.applyTo(this);
73
- }
70
+ use(module) {
71
+ module.applyTo(this);
74
72
  return this;
75
73
  }
76
74
  hasDependency(key) {
@@ -105,9 +103,8 @@ export class Container {
105
103
  * @private
106
104
  */
107
105
  getRegistrations() {
108
- return this.registrations.length
109
- ? this.parent.getRegistrations().concat(this.registrations)
110
- : this.parent.getRegistrations();
106
+ const registrations = this.parent.getRegistrations();
107
+ return this.registrations.length > 0 ? registrations.concat(this.registrations) : registrations;
111
108
  }
112
109
  /**
113
110
  * @private
@@ -35,7 +35,7 @@ export class EmptyContainer {
35
35
  use(module) {
36
36
  throw new MethodNotImplementedError();
37
37
  }
38
- addRegistration(registration) {
38
+ add(registration) {
39
39
  return this;
40
40
  }
41
41
  getKeyByAlias(alias) {
package/esm/hook.js CHANGED
@@ -1,8 +1,13 @@
1
- export const hook = (key) => (target, propertyKey) => {
2
- const hooks = Reflect.hasMetadata(key, target.constructor) ? Reflect.getMetadata(key, target.constructor) : [];
3
- Reflect.defineMetadata(key, [...hooks, propertyKey], target.constructor); // eslint-disable-line @typescript-eslint/ban-types
1
+ export const hook = (key, fn = () => []) => (target, propertyKey) => {
2
+ const hooks = Reflect.hasMetadata(key, target.constructor)
3
+ ? Reflect.getMetadata(key, target.constructor)
4
+ : new Map();
5
+ hooks.set(propertyKey, fn);
6
+ Reflect.defineMetadata(key, hooks, target.constructor); // eslint-disable-line @typescript-eslint/ban-types
4
7
  };
5
- // eslint-disable-next-line @typescript-eslint/ban-types
6
8
  export function getHooks(target, key) {
7
- return Reflect.hasMetadata(key, target.constructor) ? Reflect.getMetadata(key, target.constructor) : [];
9
+ return Reflect.hasMetadata(key, target.constructor) ? Reflect.getMetadata(key, target.constructor) : new Map();
10
+ }
11
+ export function hasHooks(target, key) {
12
+ return Reflect.hasMetadata(key, target.constructor);
8
13
  }
package/esm/index.js CHANGED
@@ -15,6 +15,6 @@ export { key, alias, scope, register } from './registration/IRegistration';
15
15
  export { MetadataInjector, inject } from './injector/MetadataInjector';
16
16
  export { SimpleInjector } from './injector/SimpleInjector';
17
17
  export { ProxyInjector } from './injector/ProxyInjector';
18
- export { getHooks, hook } from './hook';
18
+ export { getHooks, hook, hasHooks } from './hook';
19
19
  export { by } from './by';
20
- export { setMetadata, getMetadata, setParameterMetadata } from './metadata';
20
+ export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
package/esm/metadata.js CHANGED
@@ -12,3 +12,7 @@ export const setParameterMetadata = (key, value) => (target, propertyKey, parame
12
12
  export const getParameterMetadata = (key, target) => {
13
13
  return Reflect.getOwnMetadata(key, target) ?? [];
14
14
  };
15
+ export const setMethodMetadata = (key, value) => (target, propertyKey) => {
16
+ Reflect.defineMetadata(key, value, target.constructor, propertyKey);
17
+ };
18
+ export const getMethodMetadata = (key, target, propertyKey) => Reflect.getMetadata(key, target.constructor, propertyKey);
@@ -1,7 +1,7 @@
1
1
  import { getMetadata, setMetadata } from '../metadata';
2
2
  export const key = (key) => (r) => r.to(key);
3
3
  export const alias = (...aliases) => (r) => r.addAliases(...aliases);
4
- export const scope = (predicate) => (r) => r.setScopePredicate(predicate);
4
+ export const scope = (predicate) => (r) => r.when(predicate);
5
5
  const METADATA_KEY = 'registration';
6
6
  export const getTransformers = (Target) => getMetadata(Target, METADATA_KEY) ?? [];
7
7
  export const register = (...mappers) => setMetadata(METADATA_KEY, mappers);
@@ -47,7 +47,7 @@ export class Registration {
47
47
  }
48
48
  container.register(this.key, this.createProvider(), this.aliases);
49
49
  }
50
- setScopePredicate(isValidWhen) {
50
+ when(isValidWhen) {
51
51
  this.matchScope = isValidWhen;
52
52
  return this;
53
53
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "31.1.2",
3
+ "version": "31.1.4",
4
4
  "description": "Typescript IoC container",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -59,5 +59,5 @@
59
59
  "ts-node": "^10.9.1",
60
60
  "typescript": "5.4.3"
61
61
  },
62
- "gitHead": "eb63fe25a61354a09e4c88326ed40907005c9757"
62
+ "gitHead": "78877437c1aa25256dd20042e106d787db5f0701"
63
63
  }
@@ -13,6 +13,6 @@ export declare abstract class AutoMockedContainer implements IContainer {
13
13
  use(): this;
14
14
  getRegistrations(): never[];
15
15
  hasTag(): boolean;
16
- addRegistration(registration: IRegistration): this;
16
+ add(registration: IRegistration): this;
17
17
  getKeyByAlias(alias: AliasPredicate): DependencyKey;
18
18
  }
@@ -16,14 +16,14 @@ export declare class Container implements IContainer {
16
16
  parent?: IContainer;
17
17
  tags?: Tag[];
18
18
  });
19
- addRegistration(registration: IRegistration): this;
19
+ add(registration: IRegistration): this;
20
20
  register(key: DependencyKey, provider: IProvider, aliases?: Alias[]): this;
21
21
  resolve<T>(token: InjectionToken<T>, { args, child }?: ResolveOptions): T;
22
22
  createScope(...tags: Tag[]): Container;
23
23
  dispose(): void;
24
24
  getInstances(): unknown[];
25
25
  hasTag(tag: Tag): boolean;
26
- use(...modules: IContainerModule[]): this;
26
+ use(module: IContainerModule): this;
27
27
  hasDependency(key: DependencyKey): boolean;
28
28
  getKeysByAlias(predicate: AliasPredicate): DependencyKey[];
29
29
  getKeyByAlias(predicate: AliasPredicate): DependencyKey;
@@ -14,6 +14,6 @@ export declare class EmptyContainer implements IContainer {
14
14
  getInstances(): unknown[];
15
15
  removeScope(): void;
16
16
  use(module: IContainerModule): this;
17
- addRegistration(registration: IRegistration): this;
17
+ add(registration: IRegistration): this;
18
18
  getKeyByAlias(alias: AliasPredicate): DependencyKey;
19
19
  }
@@ -20,16 +20,16 @@ export interface Tagged {
20
20
  hasTag(tag: Tag): boolean;
21
21
  }
22
22
  export type Alias = string;
23
- export type AliasPredicate = (aliases: Alias[]) => boolean;
23
+ export type AliasPredicate = (aliases: Set<Alias>) => boolean;
24
24
  export interface IContainer extends Resolvable, Tagged {
25
25
  readonly isDisposed: boolean;
26
26
  createScope(...tags: Tag[]): IContainer;
27
27
  register(key: DependencyKey, value: IProvider, aliases?: Alias[]): this;
28
- addRegistration(registration: IRegistration): this;
28
+ add(registration: IRegistration): this;
29
29
  removeScope(child: IContainer): void;
30
30
  getInstances(): unknown[];
31
31
  dispose(): void;
32
- use(...modules: IContainerModule[]): this;
32
+ use(module: IContainerModule): this;
33
33
  getRegistrations(): IRegistration[];
34
34
  hasDependency(key: DependencyKey): boolean;
35
35
  getKeysByAlias(alias: AliasPredicate): DependencyKey[];
package/typings/hook.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export declare const hook: (key: string | symbol) => MethodDecorator;
2
- export declare function getHooks(target: Object, key: string | symbol): string[];
1
+ import { ArgsFn } from './provider/ArgsProvider';
2
+ export declare const hook: (key: string | symbol, fn?: ArgsFn) => MethodDecorator;
3
+ export declare function getHooks(target: object, key: string | symbol): Map<string, ArgsFn>;
4
+ export declare function hasHooks(target: object, key: string | symbol): boolean;
@@ -17,6 +17,6 @@ export { key, alias, IRegistration, scope, register } from './registration/IRegi
17
17
  export { MetadataInjector, inject } from './injector/MetadataInjector';
18
18
  export { SimpleInjector } from './injector/SimpleInjector';
19
19
  export { ProxyInjector } from './injector/ProxyInjector';
20
- export { getHooks, hook } from './hook';
20
+ export { getHooks, hook, hasHooks } from './hook';
21
21
  export { by, InstancePredicate } from './by';
22
- export { setMetadata, getMetadata, setParameterMetadata } from './metadata';
22
+ export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
@@ -3,3 +3,5 @@ export declare const setMetadata: <T>(key: string | symbol, value: T) => ClassDe
3
3
  export declare function getMetadata<T>(target: object, key: string | symbol): T | undefined;
4
4
  export declare const setParameterMetadata: (key: string | symbol, value: unknown) => ParameterDecorator;
5
5
  export declare const getParameterMetadata: (key: string | symbol, target: constructor<unknown>) => unknown[];
6
+ export declare const setMethodMetadata: (key: string, value: unknown) => MethodDecorator;
7
+ export declare const getMethodMetadata: (key: string, target: object, propertyKey: string) => unknown;
@@ -3,7 +3,7 @@ import { constructor, MapFn } from '../utils';
3
3
  export type ScopePredicate = (c: Tagged) => boolean;
4
4
  export interface IRegistration extends IContainerModule {
5
5
  addAliases(...aliases: Alias[]): this;
6
- setScopePredicate(isValidWhen: ScopePredicate): this;
6
+ when(isValidWhen: ScopePredicate): this;
7
7
  to(key: DependencyKey): this;
8
8
  }
9
9
  export declare const key: (key: DependencyKey) => MapFn<IRegistration>;
@@ -15,5 +15,5 @@ export declare class Registration<T = unknown> implements IRegistration {
15
15
  addAliases(...aliases: Alias[]): this;
16
16
  pipe(...mappers: MapFn<IProvider<T>>[]): this;
17
17
  applyTo(container: IContainer): void;
18
- setScopePredicate(isValidWhen: ScopePredicate): this;
18
+ when(isValidWhen: ScopePredicate): this;
19
19
  }