ts-ioc-container 42.0.0 → 43.0.0

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 (101) hide show
  1. package/README.md +201 -214
  2. package/cjm/container/AliasMap.js +0 -5
  3. package/cjm/container/Container.js +18 -27
  4. package/cjm/container/EmptyContainer.js +2 -11
  5. package/cjm/container/IContainer.js +0 -18
  6. package/cjm/errors/UnsupportedTokenTypeError.js +12 -0
  7. package/cjm/hooks/HookContext.js +2 -4
  8. package/cjm/hooks/hook.js +10 -49
  9. package/cjm/hooks/injectProp.js +6 -0
  10. package/cjm/hooks/onConstruct.js +8 -0
  11. package/cjm/hooks/onDispose.js +9 -0
  12. package/cjm/hooks/runner/AsyncHooksRunner.js +23 -0
  13. package/cjm/hooks/runner/HooksRunner.js +2 -0
  14. package/cjm/hooks/runner/SyncHooksRunner.js +28 -0
  15. package/cjm/index.js +35 -14
  16. package/cjm/injector/ProxyInjector.js +2 -2
  17. package/cjm/injector/inject.js +11 -23
  18. package/cjm/provider/IProvider.js +3 -2
  19. package/cjm/provider/Provider.js +2 -2
  20. package/cjm/registration/IRegistration.js +9 -6
  21. package/cjm/select.js +16 -0
  22. package/cjm/token/AliasToken.js +43 -0
  23. package/cjm/token/BindToken.js +7 -0
  24. package/cjm/token/ClassToken.js +32 -0
  25. package/cjm/token/ConstantToken.js +24 -0
  26. package/cjm/token/FunctionToken.js +24 -0
  27. package/cjm/token/InjectionToken.js +8 -0
  28. package/cjm/token/InstanceListToken.js +37 -0
  29. package/cjm/token/StringToken.js +41 -0
  30. package/cjm/token/toToken.js +25 -0
  31. package/cjm/utils.js +2 -10
  32. package/esm/container/AliasMap.js +0 -5
  33. package/esm/container/Container.js +19 -28
  34. package/esm/container/EmptyContainer.js +2 -11
  35. package/esm/container/IContainer.js +1 -16
  36. package/esm/errors/UnsupportedTokenTypeError.js +8 -0
  37. package/esm/hooks/HookContext.js +1 -2
  38. package/esm/hooks/hook.js +10 -43
  39. package/esm/hooks/injectProp.js +2 -0
  40. package/esm/hooks/onConstruct.js +4 -0
  41. package/esm/hooks/onDispose.js +6 -0
  42. package/esm/hooks/runner/AsyncHooksRunner.js +19 -0
  43. package/esm/hooks/runner/HooksRunner.js +1 -0
  44. package/esm/hooks/runner/SyncHooksRunner.js +24 -0
  45. package/esm/index.js +17 -4
  46. package/esm/injector/ProxyInjector.js +2 -2
  47. package/esm/injector/inject.js +11 -21
  48. package/esm/provider/IProvider.js +3 -2
  49. package/esm/provider/Provider.js +2 -2
  50. package/esm/registration/IRegistration.js +7 -3
  51. package/esm/select.js +13 -0
  52. package/esm/token/AliasToken.js +38 -0
  53. package/esm/token/BindToken.js +4 -0
  54. package/esm/token/ClassToken.js +28 -0
  55. package/esm/token/ConstantToken.js +20 -0
  56. package/esm/token/FunctionToken.js +20 -0
  57. package/esm/token/InjectionToken.js +3 -0
  58. package/esm/token/InstanceListToken.js +33 -0
  59. package/esm/token/StringToken.js +37 -0
  60. package/esm/token/toToken.js +21 -0
  61. package/esm/utils.js +1 -8
  62. package/package.json +2 -10
  63. package/typings/container/AliasMap.d.ts +0 -1
  64. package/typings/container/AutoMockedContainer.d.ts +3 -7
  65. package/typings/container/Container.d.ts +3 -10
  66. package/typings/container/EmptyContainer.d.ts +2 -6
  67. package/typings/container/IContainer.d.ts +7 -9
  68. package/typings/errors/UnsupportedTokenTypeError.d.ts +5 -0
  69. package/typings/hooks/HookContext.d.ts +3 -3
  70. package/typings/hooks/hook.d.ts +2 -19
  71. package/typings/hooks/injectProp.d.ts +6 -0
  72. package/typings/hooks/onConstruct.d.ts +4 -0
  73. package/typings/hooks/onDispose.d.ts +3 -0
  74. package/typings/hooks/runner/AsyncHooksRunner.d.ts +11 -0
  75. package/typings/hooks/runner/HooksRunner.d.ts +7 -0
  76. package/typings/hooks/runner/SyncHooksRunner.d.ts +6 -0
  77. package/typings/index.d.ts +18 -6
  78. package/typings/injector/IInjector.d.ts +1 -1
  79. package/typings/injector/MetadataInjector.d.ts +2 -2
  80. package/typings/injector/ProxyInjector.d.ts +2 -2
  81. package/typings/injector/SimpleInjector.d.ts +2 -2
  82. package/typings/injector/inject.d.ts +3 -5
  83. package/typings/provider/IProvider.d.ts +1 -1
  84. package/typings/registration/IRegistration.d.ts +2 -3
  85. package/typings/select.d.ts +12 -0
  86. package/typings/token/AliasToken.d.ts +15 -0
  87. package/typings/token/BindToken.d.ts +5 -0
  88. package/typings/token/ClassToken.d.ts +12 -0
  89. package/typings/token/ConstantToken.d.ts +10 -0
  90. package/typings/token/FunctionToken.d.ts +11 -0
  91. package/typings/token/InjectionToken.d.ts +14 -0
  92. package/typings/token/InstanceListToken.d.ts +13 -0
  93. package/typings/token/StringToken.d.ts +13 -0
  94. package/typings/token/toToken.d.ts +5 -0
  95. package/typings/utils.d.ts +1 -8
  96. package/cjm/DepKey.js +0 -39
  97. package/cjm/resolve.js +0 -76
  98. package/esm/DepKey.js +0 -35
  99. package/esm/resolve.js +0 -71
  100. package/typings/DepKey.d.ts +0 -15
  101. package/typings/resolve.d.ts +0 -37
package/README.md CHANGED
@@ -84,7 +84,7 @@ And `tsconfig.json` should have next options:
84
84
  ### Basic usage
85
85
 
86
86
  ```typescript
87
- import { type IContainer, by, Container, inject, Registration as R } from 'ts-ioc-container';
87
+ import { Container, type IContainer, inject, Registration as R, select } from 'ts-ioc-container';
88
88
 
89
89
  describe('Basic usage', function () {
90
90
  class Logger {
@@ -98,17 +98,17 @@ describe('Basic usage', function () {
98
98
 
99
99
  const container = new Container().addRegistration(R.fromClass(Logger).bindToKey('ILogger'));
100
100
 
101
- expect(container.resolveOne(App).logger.name).toBe('Logger');
101
+ expect(container.resolve(App).logger.name).toBe('Logger');
102
102
  });
103
103
 
104
104
  it('should inject current scope', function () {
105
105
  const root = new Container({ tags: ['root'] });
106
106
 
107
107
  class App {
108
- constructor(@inject(by.scope.current) public scope: IContainer) {}
108
+ constructor(@inject(select.scope.current) public scope: IContainer) {}
109
109
  }
110
110
 
111
- const app = root.resolveOne(App);
111
+ const app = root.resolve(App);
112
112
 
113
113
  expect(app.scope).toBe(root);
114
114
  });
@@ -125,8 +125,7 @@ Sometimes you need to create a scope of container. For example, when you want to
125
125
 
126
126
  ```typescript
127
127
  import {
128
- asKey,
129
- by,
128
+ bindTo,
130
129
  Container,
131
130
  DependencyNotFoundError,
132
131
  type IContainer,
@@ -134,10 +133,11 @@ import {
134
133
  register,
135
134
  Registration as R,
136
135
  scope,
136
+ select,
137
137
  singleton,
138
138
  } from 'ts-ioc-container';
139
139
 
140
- @register(asKey('ILogger'), scope((s) => s.hasTag('child')), singleton())
140
+ @register(bindTo('ILogger'), scope((s) => s.hasTag('child')), singleton())
141
141
  class Logger {}
142
142
 
143
143
  describe('Scopes', function () {
@@ -145,18 +145,18 @@ describe('Scopes', function () {
145
145
  const root = new Container({ tags: ['root'] }).addRegistration(R.fromClass(Logger));
146
146
  const child = root.createScope({ tags: ['child'] });
147
147
 
148
- expect(child.resolveOne('ILogger')).toBe(child.resolveOne('ILogger'));
149
- expect(() => root.resolveOne('ILogger')).toThrow(DependencyNotFoundError);
148
+ expect(child.resolve('ILogger')).toBe(child.resolve('ILogger'));
149
+ expect(() => root.resolve('ILogger')).toThrow(DependencyNotFoundError);
150
150
  });
151
151
 
152
152
  it('should inject new scope', function () {
153
153
  const root = new Container({ tags: ['root'] });
154
154
 
155
155
  class App {
156
- constructor(@inject(by.scope.create({ tags: ['child'] })) public scope: IContainer) {}
156
+ constructor(@inject(select.scope.create({ tags: ['child'] })) public scope: IContainer) {}
157
157
  }
158
158
 
159
- const app = root.resolveOne(App);
159
+ const app = root.resolve(App);
160
160
 
161
161
  expect(app.scope).not.toBe(root);
162
162
  expect(app.scope.hasTag('child')).toBe(true);
@@ -171,25 +171,25 @@ Sometimes you want to get all instances from container and its scopes. For examp
171
171
  - you can get instances from container and scope which were created by injector
172
172
 
173
173
  ```typescript
174
- import { asKey, by, Container, inject, register, Registration as R } from 'ts-ioc-container';
174
+ import { bindTo, Container, inject, register, Registration as R, select } from 'ts-ioc-container';
175
175
 
176
176
  describe('Instances', function () {
177
- @register(asKey('ILogger'))
177
+ @register(bindTo('ILogger'))
178
178
  class Logger {}
179
179
 
180
180
  it('should return injected instances', () => {
181
181
  class App {
182
- constructor(@inject(by.instances()) public loggers: Logger[]) {}
182
+ constructor(@inject(select.instances()) public loggers: Logger[]) {}
183
183
  }
184
184
 
185
185
  const root = new Container({ tags: ['root'] }).addRegistration(R.fromClass(Logger));
186
186
  const child = root.createScope({ tags: ['child'] });
187
187
 
188
- root.resolveOne('ILogger');
189
- child.resolveOne('ILogger');
188
+ root.resolve('ILogger');
189
+ child.resolve('ILogger');
190
190
 
191
- const rootApp = root.resolveOne(App);
192
- const childApp = child.resolveOne(App);
191
+ const rootApp = root.resolve(App);
192
+ const childApp = child.resolve(App);
193
193
 
194
194
  expect(childApp.loggers.length).toBe(1);
195
195
  expect(rootApp.loggers.length).toBe(2);
@@ -197,16 +197,16 @@ describe('Instances', function () {
197
197
 
198
198
  it('should return only current scope instances', () => {
199
199
  class App {
200
- constructor(@inject(by.instances().cascade(false)) public loggers: Logger[]) {}
200
+ constructor(@inject(select.instances().cascade(false)) public loggers: Logger[]) {}
201
201
  }
202
202
 
203
203
  const root = new Container({ tags: ['root'] }).addRegistration(R.fromClass(Logger));
204
204
  const child = root.createScope({ tags: ['child'] });
205
205
 
206
- root.resolveOne('ILogger');
207
- child.resolveOne('ILogger');
206
+ root.resolve('ILogger');
207
+ child.resolve('ILogger');
208
208
 
209
- const rootApp = root.resolveOne(App);
209
+ const rootApp = root.resolve(App);
210
210
 
211
211
  expect(rootApp.loggers.length).toBe(1);
212
212
  });
@@ -215,14 +215,14 @@ describe('Instances', function () {
215
215
  const isLogger = (instance: unknown) => instance instanceof Logger;
216
216
 
217
217
  class App {
218
- constructor(@inject(by.instances(isLogger)) public loggers: Logger[]) {}
218
+ constructor(@inject(select.instances(isLogger)) public loggers: Logger[]) {}
219
219
  }
220
220
 
221
221
  const container = new Container().addRegistration(R.fromClass(Logger));
222
222
 
223
- const logger0 = container.resolveOne('ILogger');
224
- const logger1 = container.resolveOne('ILogger');
225
- const app = container.resolveOne(App);
223
+ const logger0 = container.resolve('ILogger');
224
+ const logger1 = container.resolve('ILogger');
225
+ const app = container.resolve(App);
226
226
 
227
227
  expect(app.loggers).toHaveLength(2);
228
228
  expect(app.loggers[0]).toBe(logger0);
@@ -240,7 +240,7 @@ Sometimes you want to dispose container and all its scopes. For example, when yo
240
240
  - when container is disposed then it unregisters all providers and remove all instances
241
241
 
242
242
  ```typescript
243
- import { by, Container, ContainerDisposedError, Registration as R } from 'ts-ioc-container';
243
+ import { Container, ContainerDisposedError, Registration as R, select } from 'ts-ioc-container';
244
244
 
245
245
  class Logger {}
246
246
 
@@ -250,8 +250,8 @@ describe('Disposing', function () {
250
250
 
251
251
  root.dispose();
252
252
 
253
- expect(() => root.resolveOne('ILogger')).toThrow(ContainerDisposedError);
254
- expect(by.instances().resolve(root).length).toBe(0);
253
+ expect(() => root.resolve('ILogger')).toThrow(ContainerDisposedError);
254
+ expect(select.instances().resolve(root).length).toBe(0);
255
255
  });
256
256
  });
257
257
 
@@ -261,7 +261,7 @@ describe('Disposing', function () {
261
261
  Sometimes you want to create dependency only when somebody want to invoke it's method or property. This is what `lazy` is for.
262
262
 
263
263
  ```typescript
264
- import { by, Container, inject, register, Registration as R, singleton } from 'ts-ioc-container';
264
+ import { Container, inject, register, Registration as R, singleton, toToken } from 'ts-ioc-container';
265
265
 
266
266
  describe('lazy provider', () => {
267
267
  @register(singleton())
@@ -286,7 +286,7 @@ describe('lazy provider', () => {
286
286
  }
287
287
 
288
288
  class App {
289
- constructor(@inject(by.one('Service').lazy()) public service: Service) {}
289
+ constructor(@inject(toToken('Service').lazy()) public service: Service) {}
290
290
 
291
291
  run() {
292
292
  return this.service.greet();
@@ -304,8 +304,8 @@ describe('lazy provider', () => {
304
304
  const container = createContainer();
305
305
 
306
306
  // Act
307
- container.resolveOne(App);
308
- const flag = container.resolveOne<Flag>('Flag');
307
+ container.resolve(App);
308
+ const flag = container.resolve<Flag>('Flag');
309
309
 
310
310
  // Assert
311
311
  expect(flag.isSet).toBe(false);
@@ -316,8 +316,8 @@ describe('lazy provider', () => {
316
316
  const container = createContainer();
317
317
 
318
318
  // Act
319
- const app = container.resolveOne(App);
320
- const flag = container.resolveOne<Flag>('Flag');
319
+ const app = container.resolve(App);
320
+ const flag = container.resolve<Flag>('Flag');
321
321
 
322
322
  // Assert
323
323
  expect(app.run()).toBe('Hello');
@@ -329,7 +329,7 @@ describe('lazy provider', () => {
329
329
  const container = createContainer();
330
330
 
331
331
  // Act
332
- const app = container.resolveOne(App);
332
+ const app = container.resolve(App);
333
333
 
334
334
  // Assert
335
335
  expect(app.run()).toBe('Hello');
@@ -342,8 +342,8 @@ describe('lazy provider', () => {
342
342
  const container = createContainer();
343
343
 
344
344
  // Act
345
- const app = container.resolveOne(App);
346
- const flag = container.resolveOne<Flag>('Flag');
345
+ const app = container.resolve(App);
346
+ const flag = container.resolve<Flag>('Flag');
347
347
 
348
348
  // Assert
349
349
  expect(app.service.name).toBe('Service');
@@ -387,7 +387,7 @@ describe('Reflection Injector', function () {
387
387
  it('should inject dependencies by @inject decorator', function () {
388
388
  const container = new Container().addRegistration(R.fromClass(Logger).bindToKey('ILogger'));
389
389
 
390
- const app = container.resolveOne(App);
390
+ const app = container.resolve(App);
391
391
 
392
392
  expect(app.getLoggerName()).toBe('Logger');
393
393
  });
@@ -410,7 +410,7 @@ describe('SimpleInjector', function () {
410
410
  const container = new Container({ injector: new SimpleInjector() }).addRegistration(
411
411
  R.fromClass(App).bindToKey('App'),
412
412
  );
413
- const app = container.resolveOne<App>('App');
413
+ const app = container.resolve<App>('App');
414
414
 
415
415
  expect(app.container).toBeInstanceOf(Container);
416
416
  });
@@ -426,7 +426,7 @@ describe('SimpleInjector', function () {
426
426
  const container = new Container({ injector: new SimpleInjector() }).addRegistration(
427
427
  R.fromClass(App).bindToKey('App'),
428
428
  );
429
- const app = container.resolveOne<App>('App', { args: ['Hello world'] });
429
+ const app = container.resolve<App>('App', { args: ['Hello world'] });
430
430
 
431
431
  expect(app.greeting).toBe('Hello world');
432
432
  });
@@ -438,7 +438,7 @@ describe('SimpleInjector', function () {
438
438
  This type of injector injects dependencies as dictionary `Record<string, unknown>`.
439
439
 
440
440
  ```typescript
441
- import { Container, ProxyInjector, args, Registration as R } from 'ts-ioc-container';
441
+ import { args, Container, ProxyInjector, Registration as R } from 'ts-ioc-container';
442
442
 
443
443
  describe('ProxyInjector', function () {
444
444
  it('should pass dependency to constructor as dictionary', function () {
@@ -456,7 +456,7 @@ describe('ProxyInjector', function () {
456
456
  R.fromClass(Logger).bindToKey('logger'),
457
457
  );
458
458
 
459
- const app = container.resolveOne(App);
459
+ const app = container.resolve(App);
460
460
  expect(app.logger).toBeInstanceOf(Logger);
461
461
  });
462
462
 
@@ -487,7 +487,7 @@ describe('ProxyInjector', function () {
487
487
  .addRegistration(R.fromClass(App).bindToKey('App').pipe(args({ greetingTemplate })))
488
488
  .addRegistration(R.fromClass(Logger).bindToKey('logger'));
489
489
 
490
- const app = container.resolveOne<App>('App', { args: [{ name: `world` }] });
490
+ const app = container.resolve<App>('App', { args: [{ name: `world` }] });
491
491
  expect(app.greeting).toBe('Hello world');
492
492
  });
493
493
 
@@ -505,22 +505,22 @@ describe('ProxyInjector', function () {
505
505
  }
506
506
  }
507
507
 
508
- // Mock container's resolveMany to return an array with a Logger instance
508
+ // Mock container's resolveByAlias to return an array with a Logger instance
509
509
  const mockLogger = new Logger();
510
510
  const mockContainer = new Container({ injector: new ProxyInjector() });
511
- mockContainer.resolveMany = jest.fn().mockImplementation((key) => {
511
+ mockContainer.resolveByAlias = jest.fn().mockImplementation((key) => {
512
512
  // Always return the mock array for simplicity
513
513
  return [mockLogger];
514
514
  });
515
515
  mockContainer.addRegistration(R.fromClass(Service).bindToKey('service'));
516
516
 
517
- const app = mockContainer.resolveOne(App);
517
+ const app = mockContainer.resolve(App);
518
518
  expect(app.loggers).toBeInstanceOf(Array);
519
519
  expect(app.loggers.length).toBe(1);
520
520
  expect(app.loggers[0]).toBe(mockLogger);
521
521
  expect(app.service).toBeInstanceOf(Service);
522
- // Verify that resolveMany was called with the correct key
523
- expect(mockContainer.resolveMany).toHaveBeenCalledWith('loggersArray');
522
+ // Verify that resolveByAlias was called with the correct key
523
+ expect(mockContainer.resolveByAlias).toHaveBeenCalledWith('loggersArray');
524
524
  });
525
525
  });
526
526
 
@@ -537,16 +537,16 @@ Provider is dependency factory which creates dependency.
537
537
  import {
538
538
  args,
539
539
  argsFn,
540
+ bindTo,
540
541
  Container,
541
542
  inject,
543
+ lazy,
542
544
  Provider,
545
+ register,
546
+ Registration as R,
543
547
  scopeAccess,
544
548
  singleton,
545
- Registration as R,
546
- register,
547
- asKey,
548
- lazy,
549
- by,
549
+ toToken,
550
550
  } from 'ts-ioc-container';
551
551
 
552
552
  class Logger {}
@@ -568,37 +568,37 @@ class ClassWithoutTransformers {}
568
568
  describe('Provider', () => {
569
569
  it('can be registered as a function', () => {
570
570
  const container = new Container().register('ILogger', new Provider(() => new Logger()));
571
- expect(container.resolveOne('ILogger')).not.toBe(container.resolveOne('ILogger'));
571
+ expect(container.resolve('ILogger')).not.toBe(container.resolve('ILogger'));
572
572
  });
573
573
 
574
574
  it('can be registered as a value', () => {
575
575
  const container = new Container().register('ILogger', Provider.fromValue(new Logger()));
576
- expect(container.resolveOne('ILogger')).toBe(container.resolveOne('ILogger'));
576
+ expect(container.resolve('ILogger')).toBe(container.resolve('ILogger'));
577
577
  });
578
578
 
579
579
  it('can be registered as a class', () => {
580
580
  const container = new Container().register('ILogger', Provider.fromClass(Logger));
581
- expect(container.resolveOne('ILogger')).not.toBe(container.resolveOne('ILogger'));
581
+ expect(container.resolve('ILogger')).not.toBe(container.resolve('ILogger'));
582
582
  });
583
583
 
584
584
  it('can be featured by pipe method', () => {
585
585
  const root = new Container({ tags: ['root'] }).register('ILogger', Provider.fromClass(Logger).pipe(singleton()));
586
- expect(root.resolveOne('ILogger')).toBe(root.resolveOne('ILogger'));
586
+ expect(root.resolve('ILogger')).toBe(root.resolve('ILogger'));
587
587
  });
588
588
 
589
589
  it('can be created from a dependency key', () => {
590
590
  const container = new Container()
591
591
  .register('ILogger', Provider.fromClass(Logger))
592
592
  .register('LoggerAlias', Provider.fromKey('ILogger'));
593
- const logger1 = container.resolveOne('ILogger');
594
- const logger2 = container.resolveOne('LoggerAlias');
593
+ const logger1 = container.resolve('ILogger');
594
+ const logger2 = container.resolve('LoggerAlias');
595
595
  expect(logger2).toBeInstanceOf(Logger);
596
596
  expect(logger2).not.toBe(logger1);
597
597
  });
598
598
 
599
599
  it('supports lazy resolution', () => {
600
600
  const container = new Container().register('ILogger', Provider.fromClass(Logger));
601
- const lazyLogger = container.resolveOne('ILogger', { lazy: true });
601
+ const lazyLogger = container.resolve('ILogger', { lazy: true });
602
602
  expect(typeof lazyLogger).toBe('object');
603
603
  const loggerPrototype = Object.getPrototypeOf(lazyLogger);
604
604
  expect(loggerPrototype).toBeDefined();
@@ -609,7 +609,7 @@ describe('Provider', () => {
609
609
  'ConfigService',
610
610
  Provider.fromClass(ConfigService).pipe(args('/etc/config.json')),
611
611
  );
612
- const config = container.resolveOne<ConfigService>('ConfigService');
612
+ const config = container.resolve<ConfigService>('ConfigService');
613
613
  expect(config.getPath()).toBe('/etc/config.json');
614
614
  });
615
615
 
@@ -620,7 +620,7 @@ describe('Provider', () => {
620
620
  'ConfigService',
621
621
  Provider.fromClass(ConfigService).pipe(argsFn((container) => ['/dynamic/config.json'])),
622
622
  );
623
- const config = container.resolveOne<ConfigService>('ConfigService');
623
+ const config = container.resolve<ConfigService>('ConfigService');
624
624
  expect(config.getPath()).toBe('/dynamic/config.json');
625
625
  });
626
626
 
@@ -629,10 +629,10 @@ describe('Provider', () => {
629
629
  .register('Logger', Provider.fromClass(Logger))
630
630
  .register(
631
631
  'UserService',
632
- Provider.fromClass(UserService).pipe(argsFn((container) => [container.resolveOne('Logger')])),
632
+ Provider.fromClass(UserService).pipe(argsFn((container) => [container.resolve('Logger')])),
633
633
  );
634
634
  const configService = new ConfigService('/test/config.json');
635
- const userService = container.resolveOne<UserService>('UserService', { args: [configService] });
635
+ const userService = container.resolve<UserService>('UserService', { args: [configService] });
636
636
  expect(userService).toBeInstanceOf(UserService);
637
637
  });
638
638
 
@@ -645,8 +645,8 @@ describe('Provider', () => {
645
645
  );
646
646
  const adminChild = rootContainer.createScope({ tags: ['admin'] });
647
647
  const userChild = rootContainer.createScope({ tags: ['user'] });
648
- expect(() => adminChild.resolveOne('ILogger')).not.toThrow();
649
- expect(() => userChild.resolveOne('ILogger')).toThrow();
648
+ expect(() => adminChild.resolve('ILogger')).not.toThrow();
649
+ expect(() => userChild.resolve('ILogger')).toThrow();
650
650
  });
651
651
 
652
652
  it('supports chaining multiple pipe transformations', () => {
@@ -654,8 +654,8 @@ describe('Provider', () => {
654
654
  'ConfigService',
655
655
  Provider.fromClass(ConfigService).pipe(args('/default/config.json'), singleton()),
656
656
  );
657
- const config1 = container.resolveOne<ConfigService>('ConfigService');
658
- const config2 = container.resolveOne<ConfigService>('ConfigService');
657
+ const config1 = container.resolve<ConfigService>('ConfigService');
658
+ const config2 = container.resolve<ConfigService>('ConfigService');
659
659
  expect(config1).toBe(config2);
660
660
  expect(config1.getPath()).toBe('/default/config.json');
661
661
  });
@@ -664,9 +664,9 @@ describe('Provider', () => {
664
664
  const container = new Container()
665
665
  .register('ClassConstructor', Provider.fromValue(TestClass))
666
666
  .register('ClassInstance', Provider.fromClass(TestClass));
667
- const instance1 = container.resolveOne('ClassConstructor');
668
- const instance2 = container.resolveOne('ClassConstructor');
669
- const instance3 = container.resolveOne('ClassInstance');
667
+ const instance1 = container.resolve('ClassConstructor');
668
+ const instance2 = container.resolve('ClassConstructor');
669
+ const instance3 = container.resolve('ClassInstance');
670
670
  expect(instance1).toBe(TestClass);
671
671
  expect(instance2).toBe(TestClass);
672
672
  expect(instance3).toBeInstanceOf(TestClass);
@@ -678,15 +678,15 @@ describe('Provider', () => {
678
678
  .register('NumberValue', Provider.fromValue(42))
679
679
  .register('BooleanValue', Provider.fromValue(true))
680
680
  .register('ObjectValue', Provider.fromValue({ key: 'value' }));
681
- expect(container.resolveOne('StringValue')).toBe('test-string');
682
- expect(container.resolveOne('NumberValue')).toBe(42);
683
- expect(container.resolveOne('BooleanValue')).toBe(true);
684
- expect(container.resolveOne('ObjectValue')).toEqual({ key: 'value' });
681
+ expect(container.resolve('StringValue')).toBe('test-string');
682
+ expect(container.resolve('NumberValue')).toBe(42);
683
+ expect(container.resolve('BooleanValue')).toBe(true);
684
+ expect(container.resolve('ObjectValue')).toEqual({ key: 'value' });
685
685
  });
686
686
 
687
687
  it('resolves dependencies with empty args', () => {
688
688
  const container = new Container().register('Logger', Provider.fromClass(Logger));
689
- const logger = container.resolveOne('Logger', { args: [] });
689
+ const logger = container.resolve('Logger', { args: [] });
690
690
  expect(logger).toBeInstanceOf(Logger);
691
691
  });
692
692
 
@@ -696,28 +696,28 @@ describe('Provider', () => {
696
696
  const container = new Container({ tags: ['root'] }).register('Logger', provider);
697
697
  const specialChild = container.createScope({ tags: ['special'] });
698
698
  const regularChild = container.createScope({ tags: ['regular'] });
699
- expect(() => specialChild.resolveOne('Logger')).not.toThrow();
700
- expect(() => regularChild.resolveOne('Logger')).toThrow();
699
+ expect(() => specialChild.resolve('Logger')).not.toThrow();
700
+ expect(() => regularChild.resolve('Logger')).toThrow();
701
701
  });
702
702
 
703
703
  it('allows direct manipulation of args function', () => {
704
704
  const provider = Provider.fromClass(ConfigService);
705
705
  provider.setArgs(() => ['/custom/path.json']);
706
706
  const container = new Container().register('ConfigService', provider);
707
- const config = container.resolveOne<ConfigService>('ConfigService');
707
+ const config = container.resolve<ConfigService>('ConfigService');
708
708
  expect(config.getPath()).toBe('/custom/path.json');
709
709
  });
710
710
 
711
711
  it('handles class constructors when getTransformers returns null', () => {
712
712
  const container = new Container().register('NoTransformers', Provider.fromValue(ClassWithoutTransformers));
713
- const result = container.resolveOne('NoTransformers');
713
+ const result = container.resolve('NoTransformers');
714
714
  expect(result).toBe(ClassWithoutTransformers);
715
715
  });
716
716
 
717
717
  it('allows to register lazy provider', () => {
718
718
  let isLoggerCreated = false;
719
719
 
720
- @register(asKey('Logger'), lazy())
720
+ @register(bindTo('Logger'), lazy())
721
721
  class Logger {
722
722
  private logs: string[] = [];
723
723
 
@@ -743,7 +743,7 @@ describe('Provider', () => {
743
743
  }
744
744
 
745
745
  const root = new Container({ tags: ['root'] }).addRegistration(R.fromClass(Logger));
746
- const main = root.resolveClass(Main);
746
+ const main = root.resolve(Main);
747
747
 
748
748
  expect(isLoggerCreated).toBe(false);
749
749
 
@@ -753,7 +753,7 @@ describe('Provider', () => {
753
753
  });
754
754
 
755
755
  it('allows to resolve with args', () => {
756
- @register(asKey('ILogger'))
756
+ @register(bindTo('ILogger'))
757
757
  class Logger {
758
758
  readonly channel: string;
759
759
 
@@ -763,7 +763,7 @@ describe('Provider', () => {
763
763
  }
764
764
 
765
765
  class Main {
766
- constructor(@inject(by.one('ILogger').args({ channel: 'file' })) private logger: Logger) {}
766
+ constructor(@inject(toToken('ILogger').args({ channel: 'file' })) private logger: Logger) {}
767
767
 
768
768
  getChannel(): string {
769
769
  return this.logger.channel;
@@ -771,13 +771,13 @@ describe('Provider', () => {
771
771
  }
772
772
 
773
773
  const root = new Container({ tags: ['root'] }).addRegistration(R.fromClass(Logger));
774
- const main = root.resolveClass(Main);
774
+ const main = root.resolve(Main);
775
775
 
776
776
  expect(main.getChannel()).toBe('file');
777
777
  });
778
778
 
779
779
  it('allows to resolve with argsFn', () => {
780
- @register(asKey('ILogger'))
780
+ @register(bindTo('ILogger'))
781
781
  class Logger {
782
782
  readonly channel: string;
783
783
 
@@ -788,7 +788,7 @@ describe('Provider', () => {
788
788
 
789
789
  class Main {
790
790
  constructor(
791
- @inject(by.one('ILogger').argsFn((s) => [{ channel: s.resolveOne('channel') }])) private logger: Logger,
791
+ @inject(toToken('ILogger').argsFn((s) => [{ channel: s.resolve('channel') }])) private logger: Logger,
792
792
  ) {}
793
793
 
794
794
  getChannel(): string {
@@ -800,7 +800,7 @@ describe('Provider', () => {
800
800
  .addRegistration(R.fromValue('file').bindToKey('channel'))
801
801
  .addRegistration(R.fromClass(Logger));
802
802
 
803
- const main = root.resolveClass(Main);
803
+ const main = root.resolve(Main);
804
804
 
805
805
  expect(main.getChannel()).toBe('file');
806
806
  });
@@ -815,9 +815,9 @@ Sometimes you need to create only one instance of dependency per scope. For exam
815
815
  - NOTICE: if you create a scope 'A' of container 'root' then Logger of A !== Logger of root.
816
816
 
817
817
  ```typescript
818
- import { asKey, Container, register, Registration as R, singleton } from 'ts-ioc-container';
818
+ import { bindTo, Container, register, Registration as R, singleton } from 'ts-ioc-container';
819
819
 
820
- @register(asKey('logger'), singleton())
820
+ @register(bindTo('logger'), singleton())
821
821
  class Logger {}
822
822
 
823
823
  describe('Singleton', function () {
@@ -828,21 +828,21 @@ describe('Singleton', function () {
828
828
  it('should resolve the same container per every request', function () {
829
829
  const container = createContainer().addRegistration(R.fromClass(Logger));
830
830
 
831
- expect(container.resolveOne('logger')).toBe(container.resolveOne('logger'));
831
+ expect(container.resolve('logger')).toBe(container.resolve('logger'));
832
832
  });
833
833
 
834
834
  it('should resolve different dependency per scope', function () {
835
835
  const container = createContainer().addRegistration(R.fromClass(Logger));
836
836
  const child = container.createScope();
837
837
 
838
- expect(container.resolveOne('logger')).not.toBe(child.resolveOne('logger'));
838
+ expect(container.resolve('logger')).not.toBe(child.resolve('logger'));
839
839
  });
840
840
 
841
841
  it('should resolve the same dependency for scope', function () {
842
842
  const container = createContainer().addRegistration(R.fromClass(Logger));
843
843
  const child = container.createScope();
844
844
 
845
- expect(child.resolveOne('logger')).toBe(child.resolveOne('logger'));
845
+ expect(child.resolve('logger')).toBe(child.resolve('logger'));
846
846
  });
847
847
  });
848
848
 
@@ -859,19 +859,18 @@ Sometimes you want to bind some arguments to provider. This is what `ArgsProvide
859
859
  import {
860
860
  args,
861
861
  argsFn,
862
- asKey,
863
- by,
862
+ bindTo,
864
863
  Container,
865
- depKey,
866
864
  inject,
867
865
  MultiCache,
868
866
  register,
869
867
  Registration as R,
868
+ resolveByArgs,
870
869
  singleton,
870
+ StringToken,
871
871
  } from 'ts-ioc-container';
872
- import { resolveByArgs } from '../lib/provider/IProvider';
873
872
 
874
- @register(asKey('logger'))
873
+ @register(bindTo('logger'))
875
874
  class Logger {
876
875
  constructor(
877
876
  public name: string,
@@ -887,21 +886,21 @@ describe('ArgsProvider', function () {
887
886
  it('can assign argument function to provider', function () {
888
887
  const root = createContainer().addRegistration(R.fromClass(Logger).pipe(argsFn(() => ['name'])));
889
888
 
890
- const logger = root.createScope().resolveOne<Logger>('logger');
889
+ const logger = root.createScope().resolve<Logger>('logger');
891
890
  expect(logger.name).toBe('name');
892
891
  });
893
892
 
894
893
  it('can assign argument to provider', function () {
895
894
  const root = createContainer().addRegistration(R.fromClass(Logger).pipe(args('name')));
896
895
 
897
- const logger = root.resolveOne<Logger>('logger');
896
+ const logger = root.resolve<Logger>('logger');
898
897
  expect(logger.name).toBe('name');
899
898
  });
900
899
 
901
900
  it('should set provider arguments with highest priority in compare to resolve arguments', function () {
902
901
  const root = createContainer().addRegistration(R.fromClass(Logger).pipe(args('name')));
903
902
 
904
- const logger = root.resolveOne<Logger>('logger', { args: ['file'] });
903
+ const logger = root.resolve<Logger>('logger', { args: ['file'] });
905
904
 
906
905
  expect(logger.name).toBe('name');
907
906
  expect(logger.type).toBe('file');
@@ -912,15 +911,15 @@ describe('ArgsProvider', function () {
912
911
  name: string;
913
912
  }
914
913
 
915
- const IUserRepositoryKey = depKey<IRepository>('IUserRepository');
916
- const ITodoRepositoryKey = depKey<IRepository>('ITodoRepository');
914
+ const IUserRepositoryKey = new StringToken<IRepository>('IUserRepository');
915
+ const ITodoRepositoryKey = new StringToken<IRepository>('ITodoRepository');
917
916
 
918
- @register(IUserRepositoryKey.asKey)
917
+ @register(bindTo(IUserRepositoryKey))
919
918
  class UserRepository implements IRepository {
920
919
  name = 'UserRepository';
921
920
  }
922
921
 
923
- @register(ITodoRepositoryKey.asKey)
922
+ @register(bindTo(ITodoRepositoryKey))
924
923
  class TodoRepository implements IRepository {
925
924
  name = 'TodoRepository';
926
925
  }
@@ -929,17 +928,17 @@ describe('ArgsProvider', function () {
929
928
  repository: IRepository;
930
929
  }
931
930
 
932
- const IEntityManagerKey = depKey<IEntityManager>('IEntityManager');
931
+ const IEntityManagerKey = new StringToken<IEntityManager>('IEntityManager');
933
932
 
934
- @register(IEntityManagerKey.asKey, argsFn(resolveByArgs))
933
+ @register(bindTo(IEntityManagerKey), argsFn(resolveByArgs))
935
934
  class EntityManager {
936
935
  constructor(public repository: IRepository) {}
937
936
  }
938
937
 
939
938
  class Main {
940
939
  constructor(
941
- @inject(by.one(IEntityManagerKey).args(IUserRepositoryKey)) public userEntities: EntityManager,
942
- @inject(by.one(IEntityManagerKey).args(ITodoRepositoryKey)) public todoEntities: EntityManager,
940
+ @inject(IEntityManagerKey.args(IUserRepositoryKey)) public userEntities: EntityManager,
941
+ @inject(IEntityManagerKey.args(ITodoRepositoryKey)) public todoEntities: EntityManager,
943
942
  ) {}
944
943
  }
945
944
 
@@ -947,7 +946,7 @@ describe('ArgsProvider', function () {
947
946
  .addRegistration(R.fromClass(EntityManager))
948
947
  .addRegistration(R.fromClass(UserRepository))
949
948
  .addRegistration(R.fromClass(TodoRepository));
950
- const main = root.resolveOne(Main);
949
+ const main = root.resolve(Main);
951
950
 
952
951
  expect(main.userEntities.repository).toBeInstanceOf(UserRepository);
953
952
  expect(main.todoEntities.repository).toBeInstanceOf(TodoRepository);
@@ -958,15 +957,15 @@ describe('ArgsProvider', function () {
958
957
  name: string;
959
958
  }
960
959
 
961
- const IUserRepositoryKey = depKey<IRepository>('IUserRepository');
962
- const ITodoRepositoryKey = depKey<IRepository>('ITodoRepository');
960
+ const IUserRepositoryKey = new StringToken<IRepository>('IUserRepository');
961
+ const ITodoRepositoryKey = new StringToken<IRepository>('ITodoRepository');
963
962
 
964
- @register(IUserRepositoryKey.asKey)
963
+ @register(bindTo(IUserRepositoryKey))
965
964
  class UserRepository implements IRepository {
966
965
  name = 'UserRepository';
967
966
  }
968
967
 
969
- @register(ITodoRepositoryKey.asKey)
968
+ @register(bindTo(ITodoRepositoryKey))
970
969
  class TodoRepository implements IRepository {
971
970
  name = 'TodoRepository';
972
971
  }
@@ -975,17 +974,17 @@ describe('ArgsProvider', function () {
975
974
  repository: IRepository;
976
975
  }
977
976
 
978
- const IEntityManagerKey = depKey<IEntityManager>('IEntityManager');
977
+ const IEntityManagerKey = new StringToken<IEntityManager>('IEntityManager');
979
978
 
980
- @register(IEntityManagerKey.asKey, argsFn(resolveByArgs), singleton(MultiCache.fromFirstArg))
979
+ @register(bindTo(IEntityManagerKey), argsFn(resolveByArgs), singleton(MultiCache.fromFirstArg))
981
980
  class EntityManager {
982
981
  constructor(public repository: IRepository) {}
983
982
  }
984
983
 
985
984
  class Main {
986
985
  constructor(
987
- @inject(by.one(IEntityManagerKey).args(IUserRepositoryKey)) public userEntities: EntityManager,
988
- @inject(by.one(IEntityManagerKey).args(ITodoRepositoryKey)) public todoEntities: EntityManager,
986
+ @inject(IEntityManagerKey.args(IUserRepositoryKey)) public userEntities: EntityManager,
987
+ @inject(IEntityManagerKey.args(ITodoRepositoryKey)) public todoEntities: EntityManager,
989
988
  ) {}
990
989
  }
991
990
 
@@ -993,13 +992,13 @@ describe('ArgsProvider', function () {
993
992
  .addRegistration(R.fromClass(EntityManager))
994
993
  .addRegistration(R.fromClass(UserRepository))
995
994
  .addRegistration(R.fromClass(TodoRepository));
996
- const main = root.resolveOne(Main);
995
+ const main = root.resolve(Main);
997
996
 
998
- const userRepository = IEntityManagerKey.resolve(root, { args: [IUserRepositoryKey] }).repository;
997
+ const userRepository = IEntityManagerKey.args(IUserRepositoryKey).resolve(root).repository;
999
998
  expect(userRepository).toBeInstanceOf(UserRepository);
1000
999
  expect(main.userEntities.repository).toBe(userRepository);
1001
1000
 
1002
- const todoRepository = IEntityManagerKey.resolve(root, { args: [ITodoRepositoryKey] }).repository;
1001
+ const todoRepository = IEntityManagerKey.args(ITodoRepositoryKey).resolve(root).repository;
1003
1002
  expect(todoRepository).toBeInstanceOf(TodoRepository);
1004
1003
  expect(main.todoEntities.repository).toBe(todoRepository);
1005
1004
  });
@@ -1014,20 +1013,20 @@ Sometimes you want to hide dependency if somebody wants to resolve it from certa
1014
1013
 
1015
1014
  ```typescript
1016
1015
  import {
1017
- asKey,
1016
+ bindTo,
1018
1017
  Container,
1019
1018
  DependencyNotFoundError,
1020
1019
  register,
1021
1020
  Registration as R,
1022
1021
  scope,
1023
- singleton,
1024
1022
  scopeAccess,
1023
+ singleton,
1025
1024
  } from 'ts-ioc-container';
1026
1025
 
1027
1026
  describe('Visibility', function () {
1028
1027
  it('should hide from children', () => {
1029
1028
  @register(
1030
- asKey('logger'),
1029
+ bindTo('logger'),
1031
1030
  scope((s) => s.hasTag('root')),
1032
1031
  singleton(),
1033
1032
  scopeAccess(({ invocationScope, providerScope }) => invocationScope === providerScope),
@@ -1038,8 +1037,8 @@ describe('Visibility', function () {
1038
1037
 
1039
1038
  const child = parent.createScope({ tags: ['child'] });
1040
1039
 
1041
- expect(() => child.resolveOne('logger')).toThrowError(DependencyNotFoundError);
1042
- expect(parent.resolveOne('logger')).toBeInstanceOf(FileLogger);
1040
+ expect(() => child.resolve('logger')).toThrowError(DependencyNotFoundError);
1041
+ expect(parent.resolve('logger')).toBeInstanceOf(FileLogger);
1043
1042
  });
1044
1043
  });
1045
1044
 
@@ -1052,11 +1051,20 @@ Alias is needed to group keys
1052
1051
  - `Provider.fromClass(Logger).pipe(alias('logger'))`
1053
1052
 
1054
1053
  ```typescript
1055
- import { asAlias, by, Container, DependencyNotFoundError, inject, register, Registration as R, scope } from 'ts-ioc-container';
1054
+ import {
1055
+ bindTo,
1056
+ Container,
1057
+ DependencyNotFoundError,
1058
+ inject,
1059
+ register,
1060
+ Registration as R,
1061
+ scope,
1062
+ toAlias,
1063
+ } from 'ts-ioc-container';
1056
1064
 
1057
1065
  describe('alias', () => {
1058
1066
  const IMiddlewareKey = 'IMiddleware';
1059
- const middleware = register(asAlias(IMiddlewareKey));
1067
+ const middleware = register(bindTo(toAlias(IMiddlewareKey)));
1060
1068
 
1061
1069
  interface IMiddleware {
1062
1070
  applyTo(application: IApplication): void;
@@ -1084,7 +1092,7 @@ describe('alias', () => {
1084
1092
  it('should resolve by some alias', () => {
1085
1093
  class App implements IApplication {
1086
1094
  private appliedMiddleware: Set<string> = new Set();
1087
- constructor(@inject(by.many(IMiddlewareKey)) public middleware: IMiddleware[]) {}
1095
+ constructor(@inject(toAlias(IMiddlewareKey)) public middleware: IMiddleware[]) {}
1088
1096
 
1089
1097
  markMiddlewareAsApplied(name: string): void {
1090
1098
  this.appliedMiddleware.add(name);
@@ -1109,7 +1117,7 @@ describe('alias', () => {
1109
1117
  .addRegistration(R.fromClass(LoggerMiddleware))
1110
1118
  .addRegistration(R.fromClass(ErrorHandlerMiddleware));
1111
1119
 
1112
- const app = container.resolveOne(App);
1120
+ const app = container.resolve(App);
1113
1121
  app.run();
1114
1122
 
1115
1123
  expect(app.isMiddlewareApplied('LoggerMiddleware')).toBe(true);
@@ -1117,55 +1125,33 @@ describe('alias', () => {
1117
1125
  });
1118
1126
 
1119
1127
  it('should resolve by some alias', () => {
1120
- @register(asAlias('ILogger'))
1128
+ @register(bindTo(toAlias('ILogger')))
1121
1129
  class FileLogger {}
1122
1130
 
1123
1131
  const container = new Container().addRegistration(R.fromClass(FileLogger));
1124
1132
 
1125
- expect(container.resolveOne('ILogger')).toBeInstanceOf(FileLogger);
1126
- expect(() => container.resolveOne('logger')).toThrowError(DependencyNotFoundError);
1133
+ expect(container.resolveByAlias('ILogger', { takeFirst: 1 })[0]).toBeInstanceOf(FileLogger);
1134
+ expect(() => container.resolve('logger')).toThrowError(DependencyNotFoundError);
1127
1135
  });
1128
1136
 
1129
1137
  it('should resolve by alias', () => {
1130
- @register(asAlias('ILogger'), scope((s) => s.hasTag('root')))
1138
+ @register(bindTo(toAlias('ILogger')), scope((s) => s.hasTag('root')))
1131
1139
  class FileLogger {}
1132
1140
 
1133
- @register(asAlias('ILogger'), scope((s) => s.hasTag('child')))
1141
+ @register(bindTo(toAlias('ILogger')), scope((s) => s.hasTag('child')))
1134
1142
  class DbLogger {}
1135
1143
 
1136
1144
  const container = new Container({ tags: ['root'] })
1137
1145
  .addRegistration(R.fromClass(FileLogger))
1138
1146
  .addRegistration(R.fromClass(DbLogger));
1139
1147
 
1140
- const result1 = container.resolveOne('ILogger');
1148
+ const [result1] = container.resolveByAlias('ILogger', { takeFirst: 1 });
1141
1149
  const child = container.createScope({ tags: ['child'] });
1142
- const result2 = child.resolveOne('ILogger');
1150
+ const [result2] = child.resolveByAlias('ILogger', { takeFirst: 1 });
1143
1151
 
1144
1152
  expect(result1).toBeInstanceOf(FileLogger);
1145
1153
  expect(result2).toBeInstanceOf(DbLogger);
1146
1154
  });
1147
-
1148
- it('should resolve by aliases', () => {
1149
- interface ILogger {}
1150
-
1151
- @register(asAlias('ILogger'))
1152
- class FileLogger implements ILogger {}
1153
-
1154
- @register(asAlias('ILogger'))
1155
- class DbLogger implements ILogger {}
1156
-
1157
- class App {
1158
- constructor(@inject(by.aliasOne('ILogger')) public loggers: ILogger[]) {}
1159
- }
1160
-
1161
- const container = new Container().addRegistration(R.fromClass(FileLogger));
1162
-
1163
- const loggers = container.resolveOne(App).loggers;
1164
- container.addRegistration(R.fromClass(DbLogger));
1165
- const loggers2 = container.resolveOne(App).loggers;
1166
-
1167
- expect(loggers).toEqual(loggers2);
1168
- });
1169
1155
  });
1170
1156
 
1171
1157
  ```
@@ -1176,8 +1162,7 @@ Sometimes you want to decorate you class with some logic. This is what `Decorato
1176
1162
 
1177
1163
  ```typescript
1178
1164
  import {
1179
- asKey,
1180
- by,
1165
+ bindTo,
1181
1166
  Container,
1182
1167
  decorate,
1183
1168
  type IContainer,
@@ -1185,6 +1170,7 @@ import {
1185
1170
  register,
1186
1171
  Registration as R,
1187
1172
  singleton,
1173
+ toToken,
1188
1174
  } from 'ts-ioc-container';
1189
1175
 
1190
1176
  describe('lazy provider', () => {
@@ -1213,7 +1199,7 @@ describe('lazy provider', () => {
1213
1199
  class LogRepository implements IRepository {
1214
1200
  constructor(
1215
1201
  private repository: IRepository,
1216
- @inject(by.one('Logger').lazy()) private logger: Logger,
1202
+ @inject(toToken('Logger').lazy()) private logger: Logger,
1217
1203
  ) {}
1218
1204
 
1219
1205
  async save(item: Todo): Promise<void> {
@@ -1222,9 +1208,9 @@ describe('lazy provider', () => {
1222
1208
  }
1223
1209
  }
1224
1210
 
1225
- const logRepo = (dep: IRepository, scope: IContainer) => scope.resolveOne(LogRepository, { args: [dep] });
1211
+ const logRepo = (dep: IRepository, scope: IContainer) => scope.resolve(LogRepository, { args: [dep] });
1226
1212
 
1227
- @register(asKey('IRepository'), decorate(logRepo))
1213
+ @register(bindTo('IRepository'), decorate(logRepo))
1228
1214
  class TodoRepository implements IRepository {
1229
1215
  async save(item: Todo): Promise<void> {}
1230
1216
  }
@@ -1249,8 +1235,8 @@ describe('lazy provider', () => {
1249
1235
  const container = createContainer();
1250
1236
 
1251
1237
  // Act
1252
- const app = container.resolveOne(App);
1253
- const logger = container.resolveOne<Logger>('Logger');
1238
+ const app = container.resolve(App);
1239
+ const logger = container.resolve<Logger>('Logger');
1254
1240
  await app.run();
1255
1241
 
1256
1242
  // Assert
@@ -1275,31 +1261,31 @@ Sometimes you want to register provider with certain key. This is what `key` is
1275
1261
  - you can assign the same key to different registrations
1276
1262
 
1277
1263
  ```typescript
1278
- import { asAlias, asKey, Container, register, Registration as R, scope, singleton } from 'ts-ioc-container';
1264
+ import { bindTo, Container, register, Registration as R, scope, singleton, toAlias } from 'ts-ioc-container';
1279
1265
  import { DependencyMissingKeyError } from '../../lib/errors/DependencyMissingKeyError';
1280
1266
 
1281
1267
  describe('Registration module', function () {
1282
1268
  const createContainer = () => new Container({ tags: ['root'] });
1283
1269
 
1284
1270
  it('should register class', function () {
1285
- @register(asKey('ILogger'), scope((s) => s.hasTag('root')), singleton())
1271
+ @register(bindTo('ILogger'), scope((s) => s.hasTag('root')), singleton())
1286
1272
  class Logger {}
1287
1273
 
1288
1274
  const root = createContainer().addRegistration(R.fromClass(Logger));
1289
1275
 
1290
- expect(root.resolveOne('ILogger')).toBeInstanceOf(Logger);
1276
+ expect(root.resolve('ILogger')).toBeInstanceOf(Logger);
1291
1277
  });
1292
1278
 
1293
1279
  it('should register value', function () {
1294
1280
  const root = createContainer().addRegistration(R.fromValue('smth').bindToKey('ISmth'));
1295
1281
 
1296
- expect(root.resolveOne('ISmth')).toBe('smth');
1282
+ expect(root.resolve('ISmth')).toBe('smth');
1297
1283
  });
1298
1284
 
1299
1285
  it('should register fn', function () {
1300
1286
  const root = createContainer().addRegistration(R.fromFn(() => 'smth').bindToKey('ISmth'));
1301
1287
 
1302
- expect(root.resolveOne('ISmth')).toBe('smth');
1288
+ expect(root.resolve('ISmth')).toBe('smth');
1303
1289
  });
1304
1290
 
1305
1291
  it('should raise an error if key is not provider', () => {
@@ -1313,17 +1299,17 @@ describe('Registration module', function () {
1313
1299
 
1314
1300
  const root = createContainer().addRegistration(R.fromClass(FileLogger));
1315
1301
 
1316
- expect(root.resolveOne('FileLogger')).toBeInstanceOf(FileLogger);
1302
+ expect(root.resolve('FileLogger')).toBeInstanceOf(FileLogger);
1317
1303
  });
1318
1304
 
1319
1305
  it('should assign additional key which redirects to original one', function () {
1320
- @register(asKey('ILogger'), asAlias('Logger'), singleton())
1306
+ @register(bindTo('ILogger'), bindTo(toAlias('Logger')), singleton())
1321
1307
  class Logger {}
1322
1308
 
1323
1309
  const root = createContainer().addRegistration(R.fromClass(Logger));
1324
1310
 
1325
- expect(root.resolveOne('Logger')).toBeInstanceOf(Logger);
1326
- expect(root.resolveOne('ILogger')).toBeInstanceOf(Logger);
1311
+ expect(root.resolveByAlias('Logger')[0]).toBeInstanceOf(Logger);
1312
+ expect(root.resolve('ILogger')).toBeInstanceOf(Logger);
1327
1313
  });
1328
1314
  });
1329
1315
 
@@ -1335,15 +1321,15 @@ Sometimes you need to register provider only in scope which matches to certain c
1335
1321
  - `Registration.fromClass(Logger).when((container) => container.hasTag('root'))`
1336
1322
 
1337
1323
  ```typescript
1338
- import { singleton, Container, Registration as R, scope, register, asKey } from 'ts-ioc-container';
1324
+ import { bindTo, Container, register, Registration as R, scope, singleton } from 'ts-ioc-container';
1339
1325
 
1340
- @register(asKey('ILogger'), scope((s) => s.hasTag('root')), singleton())
1326
+ @register(bindTo('ILogger'), scope((s) => s.hasTag('root')), singleton())
1341
1327
  class Logger {}
1342
1328
  describe('ScopeProvider', function () {
1343
1329
  it('should return the same instance', function () {
1344
1330
  const root = new Container({ tags: ['root'] }).addRegistration(R.fromClass(Logger));
1345
1331
  const child = root.createScope();
1346
- expect(root.resolveOne('ILogger')).toBe(child.resolveOne('ILogger'));
1332
+ expect(root.resolve('ILogger')).toBe(child.resolve('ILogger'));
1347
1333
  });
1348
1334
  });
1349
1335
 
@@ -1353,12 +1339,12 @@ describe('ScopeProvider', function () {
1353
1339
  Sometimes you want to encapsulate registration logic in separate module. This is what `IContainerModule` is for.
1354
1340
 
1355
1341
  ```typescript
1356
- import { asKey, Container, type IContainer, type IContainerModule, register, Registration as R } from 'ts-ioc-container';
1342
+ import { bindTo, Container, type IContainer, type IContainerModule, register, Registration as R } from 'ts-ioc-container';
1357
1343
 
1358
- @register(asKey('ILogger'))
1344
+ @register(bindTo('ILogger'))
1359
1345
  class Logger {}
1360
1346
 
1361
- @register(asKey('ILogger'))
1347
+ @register(bindTo('ILogger'))
1362
1348
  class TestLogger {}
1363
1349
 
1364
1350
  class Production implements IContainerModule {
@@ -1381,13 +1367,13 @@ describe('Container Modules', function () {
1381
1367
  it('should register production dependencies', function () {
1382
1368
  const container = createContainer(true);
1383
1369
 
1384
- expect(container.resolveOne('ILogger')).toBeInstanceOf(Logger);
1370
+ expect(container.resolve('ILogger')).toBeInstanceOf(Logger);
1385
1371
  });
1386
1372
 
1387
1373
  it('should register development dependencies', function () {
1388
1374
  const container = createContainer(false);
1389
1375
 
1390
- expect(container.resolveOne('ILogger')).toBeInstanceOf(TestLogger);
1376
+ expect(container.resolve('ILogger')).toBeInstanceOf(TestLogger);
1391
1377
  });
1392
1378
  });
1393
1379
 
@@ -1399,7 +1385,7 @@ Sometimes you need to invoke methods after construct or dispose of class. This i
1399
1385
  ### OnConstruct
1400
1386
  ```typescript
1401
1387
  import {
1402
- asKey,
1388
+ bindTo,
1403
1389
  type constructor,
1404
1390
  Container,
1405
1391
  hook,
@@ -1409,20 +1395,21 @@ import {
1409
1395
  MetadataInjector,
1410
1396
  register,
1411
1397
  Registration as R,
1412
- runHooks,
1398
+ SyncHooksRunner,
1413
1399
  } from 'ts-ioc-container';
1414
1400
 
1401
+ const onConstructHooksRunner = new SyncHooksRunner('onConstruct');
1415
1402
  class MyInjector implements IInjector {
1416
1403
  private injector = new MetadataInjector();
1417
1404
 
1418
1405
  resolve<T>(container: IContainer, value: constructor<T>, options: InjectOptions): T {
1419
1406
  const instance = this.injector.resolve(container, value, options);
1420
- runHooks(instance as object, 'onConstruct', { scope: container });
1407
+ onConstructHooksRunner.execute(instance as object, { scope: container });
1421
1408
  return instance;
1422
1409
  }
1423
1410
  }
1424
1411
 
1425
- @register(asKey('logger'))
1412
+ @register(bindTo('logger'))
1426
1413
  class Logger {
1427
1414
  isReady = false;
1428
1415
 
@@ -1442,7 +1429,7 @@ describe('onConstruct', function () {
1442
1429
  it('should make logger be ready on resolve', function () {
1443
1430
  const container = new Container({ injector: new MyInjector() }).addRegistration(R.fromClass(Logger));
1444
1431
 
1445
- const logger = container.resolveOne<Logger>('logger');
1432
+ const logger = container.resolve<Logger>('logger');
1446
1433
 
1447
1434
  expect(logger.isReady).toBe(true);
1448
1435
  });
@@ -1452,9 +1439,20 @@ describe('onConstruct', function () {
1452
1439
 
1453
1440
  ### OnDispose
1454
1441
  ```typescript
1455
- import { asKey, by, Container, hook, inject, register, Registration as R, runHooks, singleton } from 'ts-ioc-container';
1442
+ import {
1443
+ bindTo,
1444
+ Container,
1445
+ hook,
1446
+ inject,
1447
+ register,
1448
+ Registration as R,
1449
+ select,
1450
+ singleton,
1451
+ SyncHooksRunner,
1452
+ } from 'ts-ioc-container';
1456
1453
 
1457
- @register(asKey('logsRepo'), singleton())
1454
+ const onDisposeHookRunner = new SyncHooksRunner('onDispose');
1455
+ @register(bindTo('logsRepo'), singleton())
1458
1456
  class LogsRepo {
1459
1457
  savedLogs: string[] = [];
1460
1458
 
@@ -1463,7 +1461,7 @@ class LogsRepo {
1463
1461
  }
1464
1462
  }
1465
1463
 
1466
- @register(asKey('logger'))
1464
+ @register(bindTo('logger'))
1467
1465
  class Logger {
1468
1466
  @hook('onDispose', ({ instance, methodName }) => {
1469
1467
  // @ts-ignore
@@ -1493,14 +1491,14 @@ describe('onDispose', function () {
1493
1491
  it('should invoke hooks on all instances', async function () {
1494
1492
  const container = new Container().addRegistration(R.fromClass(Logger)).addRegistration(R.fromClass(LogsRepo));
1495
1493
 
1496
- const logger = container.resolveOne<Logger>('logger');
1494
+ const logger = container.resolve<Logger>('logger');
1497
1495
  logger.log('Hello');
1498
1496
 
1499
- for (const instance of by.instances().resolve(container)) {
1500
- runHooks(instance as object, 'onDispose', { scope: container });
1497
+ for (const instance of select.instances().resolve(container)) {
1498
+ onDisposeHookRunner.execute(instance as object, { scope: container });
1501
1499
  }
1502
1500
 
1503
- expect(container.resolveOne<LogsRepo>('logsRepo').savedLogs.join(',')).toBe('Hello,world');
1501
+ expect(container.resolve<LogsRepo>('logsRepo').savedLogs.join(',')).toBe('Hello,world');
1504
1502
  });
1505
1503
  });
1506
1504
 
@@ -1509,8 +1507,9 @@ describe('onDispose', function () {
1509
1507
  ### Inject property
1510
1508
 
1511
1509
  ```typescript
1512
- import { Container, hook, injectProp, Registration, runHooks } from 'ts-ioc-container';
1510
+ import { Container, hook, injectProp, Registration, SyncHooksRunner } from 'ts-ioc-container';
1513
1511
 
1512
+ const onInitHookRunner = new SyncHooksRunner('onInit');
1514
1513
  describe('inject property', () => {
1515
1514
  it('should inject property', () => {
1516
1515
  class App {
@@ -1520,8 +1519,8 @@ describe('inject property', () => {
1520
1519
  const expected = 'Hello world!';
1521
1520
 
1522
1521
  const container = new Container().addRegistration(Registration.fromValue(expected).bindToKey('greeting'));
1523
- const app = container.resolveOne(App);
1524
- runHooks(app as object, 'onInit', { scope: container });
1522
+ const app = container.resolve(App);
1523
+ onInitHookRunner.execute(app as object, { scope: container });
1525
1524
 
1526
1525
  expect(app.greeting).toBe(expected);
1527
1526
  });
@@ -1539,7 +1538,7 @@ import { type IMock, Mock } from 'moq.ts';
1539
1538
  export class MoqContainer extends AutoMockedContainer {
1540
1539
  private mocks = new Map<DependencyKey, IMock<any>>();
1541
1540
 
1542
- resolveOne<T>(key: DependencyKey): T {
1541
+ resolve<T>(key: DependencyKey): T {
1543
1542
  return this.resolveMock<T>(key).object();
1544
1543
  }
1545
1544
 
@@ -1550,19 +1549,7 @@ export class MoqContainer extends AutoMockedContainer {
1550
1549
  return this.mocks.get(key) as IMock<T>;
1551
1550
  }
1552
1551
 
1553
- resolveClass<T>(target: any, options?: { args?: unknown[] }): T {
1554
- throw new Error('Method not implemented.');
1555
- }
1556
-
1557
- resolveOneByKey<T>(key: DependencyKey): T {
1558
- return this.resolveMock<T>(key).object();
1559
- }
1560
-
1561
- resolveMany<T>(alias: DependencyKey): T[] {
1562
- throw new Error('Method not implemented.');
1563
- }
1564
-
1565
- resolveOneByAlias<T>(key: DependencyKey): T {
1552
+ resolveByAlias<T>(alias: DependencyKey): T[] {
1566
1553
  throw new Error('Method not implemented.');
1567
1554
  }
1568
1555
  }
@@ -1579,7 +1566,7 @@ describe('Mocking', () => {
1579
1566
  const engineMock = mockContainer.resolveMock<IEngine>('IEngine');
1580
1567
  engineMock.setup((i) => i.getRegistrationNumber()).returns('123');
1581
1568
 
1582
- const engine = container.resolveOne<IEngine>('IEngine');
1569
+ const engine = container.resolve<IEngine>('IEngine');
1583
1570
 
1584
1571
  expect(engine.getRegistrationNumber()).toBe('123');
1585
1572
  });