ts-ioc-container 23.2.11 → 23.3.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 (50) hide show
  1. package/README.md +269 -159
  2. package/cjs/container/Container.d.ts +1 -1
  3. package/cjs/index.d.ts +5 -3
  4. package/cjs/index.js +12 -36
  5. package/cjs/index.js.map +1 -1
  6. package/cjs/{IInjector.d.ts → injector/IInjector.d.ts} +2 -2
  7. package/{esm → cjs/injector}/IInjector.js.map +1 -1
  8. package/cjs/injector/ProxyInjector.d.ts +6 -0
  9. package/cjs/injector/ProxyInjector.js +42 -0
  10. package/cjs/injector/ProxyInjector.js.map +1 -0
  11. package/cjs/injector/ReflectionInjector.d.ts +10 -0
  12. package/cjs/injector/ReflectionInjector.js +68 -0
  13. package/cjs/injector/ReflectionInjector.js.map +1 -0
  14. package/cjs/injector/SimpleInjector.d.ts +6 -0
  15. package/cjs/injector/SimpleInjector.js +42 -0
  16. package/cjs/injector/SimpleInjector.js.map +1 -0
  17. package/cjs/provider/ArgsProvider.d.ts +2 -2
  18. package/cjs/provider/ArgsProvider.js.map +1 -1
  19. package/cjs/reflection.d.ts +2 -0
  20. package/cjs/reflection.js +38 -1
  21. package/cjs/reflection.js.map +1 -1
  22. package/cjs/utils.d.ts +2 -0
  23. package/cjs/utils.js +37 -1
  24. package/cjs/utils.js.map +1 -1
  25. package/esm/container/Container.d.ts +1 -1
  26. package/esm/index.d.ts +5 -3
  27. package/esm/index.js +4 -1
  28. package/esm/index.js.map +1 -1
  29. package/esm/{IInjector.d.ts → injector/IInjector.d.ts} +2 -2
  30. package/{cjs → esm/injector}/IInjector.js.map +1 -1
  31. package/esm/injector/ProxyInjector.d.ts +6 -0
  32. package/esm/injector/ProxyInjector.js +20 -0
  33. package/esm/injector/ProxyInjector.js.map +1 -0
  34. package/esm/injector/ReflectionInjector.d.ts +10 -0
  35. package/esm/injector/ReflectionInjector.js +19 -0
  36. package/esm/injector/ReflectionInjector.js.map +1 -0
  37. package/esm/injector/SimpleInjector.d.ts +6 -0
  38. package/esm/injector/SimpleInjector.js +6 -0
  39. package/esm/injector/SimpleInjector.js.map +1 -0
  40. package/esm/provider/ArgsProvider.d.ts +2 -2
  41. package/esm/provider/ArgsProvider.js.map +1 -1
  42. package/esm/reflection.d.ts +2 -0
  43. package/esm/reflection.js +8 -0
  44. package/esm/reflection.js.map +1 -1
  45. package/esm/utils.d.ts +2 -0
  46. package/esm/utils.js +14 -0
  47. package/esm/utils.js.map +1 -1
  48. package/package.json +2 -3
  49. /package/cjs/{IInjector.js → injector/IInjector.js} +0 -0
  50. /package/esm/{IInjector.js → injector/IInjector.js} +0 -0
package/README.md CHANGED
@@ -19,13 +19,20 @@
19
19
 
20
20
  ## Install
21
21
  ```shell script
22
- npm install ts-ioc-container ts-constructor-injector reflect-metadata
22
+ npm install ts-ioc-container reflect-metadata
23
23
  ```
24
24
  ```shell script
25
- yarn add ts-ioc-container ts-constructor-injector reflect-metadata
25
+ yarn add ts-ioc-container reflect-metadata
26
26
  ```
27
27
 
28
- ## tsconfig.json
28
+ ## Setup
29
+ ### reflect-metadata
30
+ Add it in main file of your project. It should be first line of code.
31
+ ```typescript
32
+ import 'reflect-metadata';
33
+ ```
34
+
35
+ ### tsconfig.json
29
36
  ```json
30
37
  {
31
38
  "compilerOptions": {
@@ -35,21 +42,103 @@ yarn add ts-ioc-container ts-constructor-injector reflect-metadata
35
42
  }
36
43
  ```
37
44
 
45
+ ## Container
46
+ Container consists of:
47
+
48
+ - Injector - injects dependencies to constructor
49
+ - Providers - templates that create instances of dependencies
50
+
51
+ ### Basic usage
52
+
53
+ ```typescript
54
+ import 'reflect-metadata';
55
+ import { Container } from "ts-ioc-container";
56
+
57
+ class Logger {
58
+ public name = 'Logger';
59
+ }
60
+
61
+ class App {
62
+ constructor(@inject(by('ILogger')) public logger: ILogger) {
63
+ }
64
+ }
65
+
66
+ const container = new Container(new ReflectionInjector()).register('ILogger', Provider.fromClass(Logger));
67
+ container.resolve(App).resolve.logger.name === 'Logger'; // true
68
+
69
+ container.dispose();
70
+ ```
71
+
72
+ ### Scopes
73
+ - scope - is a container that can be created from another container. It's a sub-container.
74
+ - NOTICE: when you create a scope of container then all providers are cloned to new scope. Every provider has method `clone` that clones itself.
75
+
76
+ ```typescript
77
+ import { Container, ReflectionInjector } from "ts-ioc-container";
78
+
79
+ const container = new Container(new ReflectionInjector());
80
+ const scope = container.createScope();
81
+ ```
82
+
83
+ ### Tags
38
84
 
39
- ## Injector
40
- As long as injector is not part of container, you can implement injection on your choice (simple, proxy, based on reflection).
85
+ - tag - is a string that can be used mark each container and scope
86
+ - every provider can be registered per certain tags and cannot be resolved from container with other tags. Only from parent one with certain tags.
87
+ - NOTICE: when you create a scope of container with tags which not includes in provider tags then this provider will not be cloned to new scope.
41
88
 
42
- ### Reflection injector (recommended)
89
+ ```typescript
90
+ import { Container, perTags, ReflectionInjector } from "ts-ioc-container";
91
+
92
+ const container = new Container(new ReflectionInjector(), { tags: ['root'] }).register('ILogger', Provider.fromClass(Logger).pipe(perTags('root')));
93
+ const scope = container.createScope(['child']);
94
+
95
+ scope.resolve('ILogger'); // it will be resolved from container, not from scope
96
+ ```
97
+
98
+ ### Instances
99
+ - you can get instances from container and scope which were created by injector
100
+
101
+ ```typescript
102
+ import { Container, ReflectionInjector } from "ts-ioc-container";
103
+
104
+ const container = new Container(new ReflectionInjector()).register('ILogger', Provider.fromClass(Logger));
105
+ const scope = container.createScope();
106
+
107
+ const logger1 = container.resolve('ILogger');
108
+ const logger2 = scope.resolve('ILogger');
109
+
110
+ expect(scope.getInstances().length).toBe(1);
111
+ expect(container.getInstances().length).toBe(2);
112
+ ```
113
+
114
+ ### Disposing
115
+ - container can be disposed
116
+ - when container is disposed then all scopes are disposed too
117
+ - when container is disposed then it unregisters all providers and remove all instances
43
118
 
44
119
  ```typescript
45
- import { Container, IContainer, IInjector, Provider, by } from "ts-request-mediator";
46
- import { inject, resolve } from "ts-constructor-injector";
120
+ import { asSingleton, Container, perTags, ReflectionInjector, ContainerDisposedError } from "ts-ioc-container";
47
121
 
48
- const injector: IInjector = {
49
- resolve<T>(container: IContainer, Target: constructor<T>, ...deps: unknown[]): T {
50
- return resolve(container)(Target, ...deps);
51
- },
52
- };
122
+ const container = new Container(new ReflectionInjector(), { tags: ['root'] }).register('ILogger', Provider.fromClass(Logger));
123
+ const scope = container.createScope(['child']);
124
+
125
+ const logger = scope.resolve('ILogger');
126
+ container.dispose();
127
+
128
+ expect(() => scope.resolve('ILogger')).toThrow(ContainerDisposedError);
129
+ expect(() => container.resolve('ILogger')).toThrow(ContainerDisposedError);
130
+ expect(container.getInstances().length).toBe(0);
131
+ ```
132
+
133
+ ## Injectors
134
+ - `ReflectionInjector` - injects dependencies using `@inject` decorator
135
+ - `ProxyInjector` - injects dependencies as dictionary `Record<string, unknown>`
136
+ - `SimpleInjector` - just passes container to constructor with others arguments
137
+
138
+ ### Reflection injector
139
+
140
+ ```typescript
141
+ import { Container, IContainer, IInjector, Provider, by, inject, resolve } from "ts-ioc-container";
53
142
 
54
143
  class Logger implements ILogger {
55
144
  info(message: string) {
@@ -58,15 +147,19 @@ class Logger implements ILogger {
58
147
  }
59
148
 
60
149
  class App {
61
- constructor(@inject(by('ILogger')) private logger: ILogger) {
150
+ constructor(@inject((container, ...args) => container.resolve('ILogger', ...args)) private logger: ILogger) {
62
151
  }
63
152
 
153
+ // OR
154
+ // constructor(@inject(by('ILogger')) private logger: ILogger) {
155
+ // }
156
+
64
157
  run() {
65
158
  this.logger.info('Hello world');
66
159
  }
67
160
  }
68
161
 
69
- const container = new Container(injector)
162
+ const container = new Container(new ReflectionInjector())
70
163
  .register('ILogger', Provider.fromClass(Logger));
71
164
 
72
165
  const app = container.resolve(App);
@@ -76,13 +169,7 @@ app.run();
76
169
  ### Simple injector
77
170
 
78
171
  ```typescript
79
- import { IContainer } from "ts-request-mediator";
80
-
81
- const injector: IInjector = {
82
- resolve<T>(container: IContainer, Target: constructor<T>, ...deps: unknown[]): T {
83
- return new Target(container, ...deps);
84
- },
85
- };
172
+ import { SimpleInjector, IContainer } from "ts-ioc-container";
86
173
 
87
174
  class Logger implements ILogger {
88
175
  info(message: string) {
@@ -96,13 +183,13 @@ class App {
96
183
  constructor(private container: IContainer) {
97
184
  this.logger = container.resolve('ILogger');
98
185
  }
99
-
186
+
100
187
  run() {
101
188
  this.logger.info('Hello world');
102
189
  }
103
190
  }
104
191
 
105
- const container = new Container(injector)
192
+ const container = new Container(new SimpleInjector())
106
193
  .register('ILogger', Provider.fromClass(Logger));
107
194
 
108
195
  const app = container.resolve(App);
@@ -112,24 +199,7 @@ app.run();
112
199
  ### Proxy injector
113
200
 
114
201
  ```typescript
115
- import { IContainer } from "ts-request-mediator";
116
-
117
- const injector: IInjector = {
118
- resolve<T>(container: IContainer, Target: constructor<T>, ...deps: unknown[]): T {
119
- const args = deps.reduce((acc, it) => ({ ...acc, ...it }), {});
120
- const proxy = new Proxy(
121
- {},
122
- {
123
- // eslint-disable-next-line @typescript-eslint/ban-types
124
- get(target: {}, prop: string | symbol): any {
125
- // eslint-disable-next-line no-prototype-builtins
126
- return args.hasOwnProperty(prop) ? args[prop] : container.resolve(prop);
127
- },
128
- },
129
- );
130
- return new Target(proxy);
131
- },
132
- };
202
+ import { ProxyInjector, IContainer } from "ts-ioc-container";
133
203
 
134
204
  class Logger implements ILogger {
135
205
  info(message: string) {
@@ -140,103 +210,190 @@ class Logger implements ILogger {
140
210
  class App {
141
211
  private logger: ILogger;
142
212
 
143
- constructor({logger}: {logger: ILogger}) {
213
+ constructor({ logger }: { logger: ILogger }) {
144
214
  this.logger = logger;
145
215
  }
146
-
216
+
147
217
  run() {
148
218
  this.logger.info('Hello world');
149
219
  }
150
220
  }
151
221
 
152
- const container = new Container(injector)
222
+ const container = new Container(new ProxyInjector())
153
223
  .register('logger', Provider.fromClass(Logger));
154
224
 
155
225
  const app = container.resolve(App);
156
226
  app.run();
157
227
  ```
158
228
 
159
- ## Provider
229
+ ## Providers
230
+ All providers are registered in container and cloned for every sub-scope.
231
+
232
+ - `Provider` - basic provider
233
+ - `SingletonProvider` - provider that creates only one instance in every scope where it's resolved
234
+ - `TaggedProvider` - provider that can be resolved only from container with certain tags and their sub scopes
235
+ - `ArgsProvider` - provider that encapsulates arguments to pass it to constructor.
236
+
237
+ ### Provider
160
238
 
161
- - `Provider.fromClass` - creates dependency provider from class
162
- - `.pipe` - decorates provider by features and returns new provider
163
- - `asSingleton()` - makes provider singleton (singleton in every scope)
164
- - `perTags(...tags: string[])` - makes provider available only in scope with certain tags and their sub scopes
165
- - `withArgs(...args: unknown[])` - passes arguments to constructor
166
- - `withArgsFn(fn: (scope: IContainer) => unknown[])` - passes arguments to constructor as function result
239
+ From function
167
240
 
168
241
  ```typescript
169
- import { Provider, asSingleton, perTags, withArgs, withArgsFn } from "ts-request-mediator";
242
+ import { Provider } from "ts-ioc-container";
170
243
 
171
- const container = new Container(injector, { tags: ['root'] });
172
- container.register('ILogger', new Provider((container, ...args) => new Logger(...args)));
244
+ container.register('ILogger', new Provider((container, ...args) => new Logger(container, ...args)));
245
+ ```
173
246
 
174
- // Available only in root scope and all his children
175
- container.register('ILogger', Provider.fromClass(Logger).pipe(perTags('root')));
247
+ From class
176
248
 
177
- // Singleton per root tag and all his children
178
- container.register('ILogger', Provider.fromClass(Logger).pipe(asSingleton(), perTags('root')));
249
+ ```typescript
250
+ import { Provider } from "ts-ioc-container";
179
251
 
180
- // singleton for scope with tag1 or tag2
181
- container.register('ILogger', Provider.fromClass(Logger).pipe(asSingleton(), perTags('tag1', 'tag2')));
252
+ container.register('ILogger', Provider.fromClass(Logger));
253
+ ```
182
254
 
183
- // singleton in every scope
184
- container.register('ILogger', Provider.fromClass(Logger).pipe(withArgs('dev'), asSingleton()));
255
+ From value
185
256
 
186
- // singleton in every scope
187
- container.register('ILogger', Provider.fromClass(Logger).pipe(withArgsFn((scope) => [scope.resolve('isTestEnv') ? 'dev' : 'prod']), asSingleton()));
257
+ ```typescript
258
+ import { Provider } from "ts-ioc-container";
188
259
 
189
260
  container.register('ILogger', Provider.fromValue(new Logger()));
190
261
  ```
191
262
 
192
- ## Registration module (Provider + DependencyKey)
263
+ `pipe` - decorates provider by other providers
193
264
 
194
265
  ```typescript
195
- import { asSingleton, perTags, forKey, Registration } from "ts-request-mediator";
266
+ import { asSingleton, perTags, Provider, SingletonProvider, TaggedProvider } from "ts-ioc-container";
196
267
 
197
- @forKey('ILogger')
268
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new SingletonProvider(provider)), (provider) => new TaggedProvider(provider, ['root']));
269
+
270
+ // OR
271
+ container.register('ILogger', Provider.fromClass(Logger).pipe(asSingleton(), perTags('root')));
272
+
273
+ // OR
198
274
  @provider(asSingleton(), perTags('root'))
199
275
  class Logger {
200
- info(message: string) {
201
- console.log(message);
276
+ }
277
+
278
+ container.register('ILogger', Provider.fromClass(Logger));
279
+ ```
280
+
281
+ ### Singleton provider
282
+
283
+ - Singleton provider creates only one instance in every scope where it's resolved.
284
+ - NOTICE: if you create a scope 'A' of container 'root' then Logger of A !== Logger of root.
285
+
286
+ ```typescript
287
+ import { Provider, SingletonProvider, asSingleton } from "ts-ioc-container";
288
+
289
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new SingletonProvider(provider)));
290
+ // OR
291
+ container.register('ILogger', Provider.fromClass(Logger).pipe(asSingleton()));
292
+
293
+ container.resolve('ILogger') === container.resolve('ILogger'); // true
294
+
295
+ const scope = container.createScope();
296
+ scope.resolve('ILogger') === scope.resolve('ILogger'); // true
297
+ container.resolve('ILogger') !== scope.resolve('ILogger'); // true. NOTICE: because every provider is cloned for every child scope from parent one
298
+ ```
299
+
300
+ ### Tagged provider
301
+ You need tagged provider when you want to resolve provider only from container with certain tags and their sub scopes.
302
+ It doesn't make a clones in scopes with tags that are not in provider's tags. Usually it's used with `SingletonProvider`.
303
+
304
+ ```typescript
305
+ import { Provider, TaggedProvider, asSingleton, perTags } from "ts-ioc-container";
306
+
307
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new TaggedProvider(provider, ['root'])));
308
+ // OR
309
+ container.register('ILogger', Provider.fromClass(Logger).pipe(perTags('root', 'parent')));
310
+
311
+ // with sigleton
312
+ container.register('ILogger', Provider.fromClass(Logger).pipe(perTags('root', 'parent')).pipe(asSingleton()));
313
+ container.resolve('ILogger') === container.resolve('ILogger'); // true
314
+
315
+ const scope = container.createScope();
316
+ scope.resolve('ILogger') === scope.resolve('ILogger'); // true
317
+ container.resolve('ILogger') === scope.resolve('ILogger'); // true
318
+ ```
319
+
320
+ ### Args provider
321
+ - You need args provider when you want to pass arguments to constructor on step when you compose container.
322
+ - NOTICE: args from this provider has higher priority than args from `resolve` method.
323
+
324
+ ```typescript
325
+ import { Provider, ArgsProvider, withArgs, withArgsFn } from "ts-ioc-container";
326
+
327
+ class Logger {
328
+ constructor(public type: string, public name: string) {
329
+ }
330
+ }
331
+
332
+ container.register('ILogger', Provider.fromClass(Logger).pipe((provider) => new ArgsProvider(provider, () => ['FileLogger'])));
333
+
334
+ // OR
335
+ container.register('ILogger', Provider.fromClass(Logger).pipe(withArgsFn(() => ['FileLogger'])));
336
+ // OR
337
+ container.register('ILogger', Provider.fromClass(Logger).pipe(withArgs('FileLogger')));
338
+
339
+ container.resolve('ILogger', 'Main').type === 'FileLogger'; // true
340
+ container.resolve('ILogger', 'Main').name === 'Main'; // true
341
+ ```
342
+
343
+ ## Container modules
344
+
345
+ if you want to encapsulate some logic to enrich container you can use `IContainerModule`.
346
+
347
+ ```typescript
348
+ import { Registration } from "ts-ioc-container";
349
+
350
+ class Development implements IContainerModule {
351
+ applyTo(container: IContainer): void {
352
+ container.add(Registration.fromClass(DevLogger));
353
+ }
354
+ }
355
+
356
+ class Production implements IContainerModule {
357
+ applyTo(container: IContainer): void {
358
+ container.add(Registration.fromClass(ProdLogger));
202
359
  }
203
360
  }
204
361
 
205
362
  const container = new Container(injector, { tags: ['root'] })
206
- .add(Registration.fromClass(Logger));
207
- const logger = container.resolve<ILogger>('ILogger');
208
- logger.info('Hello world');
363
+ .add(Registration.fromClass(Logger))
364
+ .add(process.env.NODE_ENV === 'production' ? new Production() : new Development());
209
365
  ```
210
366
 
211
- ## Decorators
367
+ ## Registration module (Provider + DependencyKey)
368
+ It's built-in module that encapsulates logic of registration provider by dependency key `forKey`. Just a sugar
212
369
 
213
370
  ```typescript
214
- import { asSingleton, perTags, forKey, by, Registration } from "ts-request-mediator";
215
- import { inject } from "ts-constructor-injector";
371
+ import { asSingleton, perTags, forKey, Registration, Provider } from "ts-ioc-container";
216
372
 
217
- @forKey('IEngine')
373
+ @forKey('ILogger')
218
374
  @provider(asSingleton(), perTags('root'))
219
- class Engine {
220
- constructor(@inject(by('ILogger')) private logger: ILogger) {
375
+ class Logger {
376
+ info(message: string) {
377
+ console.log(message);
221
378
  }
222
379
  }
223
380
 
224
- // OR
381
+ container.register(Registration.fromClass(Logger));
225
382
 
226
- const perRoot = provider(asSingleton(), perTags('root'))
383
+ // OR
227
384
 
228
- @perRoot
229
- @forKey('IEngine')
230
- class Engine {
231
- constructor(@inject(by('ILogger')) private logger: ILogger) {
385
+ @provider(asSingleton(), perTags('root'))
386
+ class Logger {
387
+ info(message: string) {
388
+ console.log(message);
232
389
  }
233
390
  }
234
391
 
235
- const container = new Container(injector, { tags: ['root'] })
236
- .add(Registration.fromClass(Engine));
392
+ container.register('ILogger', Provider.fromClass(Logger));
237
393
  ```
238
394
 
239
395
  ## Hooks
396
+ You can mark methods of your classes as hooks. It's useful when you want to do something after construct of dispose classes.
240
397
 
241
398
  ```typescript
242
399
  import {
@@ -245,8 +402,25 @@ import {
245
402
  ContainerHook,
246
403
  Injector,
247
404
  Registration,
248
- } from "ts-request-mediator";
249
- import { getHooks, hook } from "ts-constructor-injector";
405
+ getHooks,
406
+ hook,
407
+ } from "ts-ioc-container";
408
+
409
+ const onConstruct = hook('onConstruct');
410
+ const onDispose = hook('onDispose');
411
+
412
+ class MyInjector implements IInjector {
413
+ private injector = new ReflectionInjector();
414
+
415
+ resolve<T>(container: IContainer, value: constructor<T>, ...deps: unknown[]): T {
416
+ const instance = this.injector.resolve(container, value, ...deps);
417
+ for (const h of getHooks(instance, 'onConstruct')) {
418
+ // @ts-ignore
419
+ instance[h]();
420
+ }
421
+ return instance;
422
+ }
423
+ }
250
424
 
251
425
  @forKey('ILogger')
252
426
  class Logger {
@@ -261,87 +435,27 @@ class Logger {
261
435
  }
262
436
  }
263
437
 
264
- const injector: IInjector = {
265
- resolve<T>(container: IContainer, value: constructor<T>, ...deps: unknown[]): T {
266
- const instance = resolve(container)(value, ...deps);
267
- for (const h of getHooks(instance, 'OnConstruct')) {
268
- // @ts-ignore
269
- instance[h]();
270
- }
271
- return instance;
272
- },
273
- }
274
-
275
- const container = new Container(injector)
438
+ const container = new Container(new MyInjector())
276
439
  .add(Registration.fromClass(Logger));
277
440
  const logger = container.resolve<ILogger>('ILogger'); // initialized
441
+
278
442
  for (const instance of container.getInstances()) {
279
- for (const h of getHooks(instance, 'OnDispose')) {
443
+ for (const h of getHooks(instance, 'onDispose')) {
280
444
  // @ts-ignore
281
- instance[h]();
445
+ instance[h](); // disposed
282
446
  }
283
447
  }
284
448
  ```
285
449
 
286
- ## Scopes (child containers)
287
-
288
- - tags - you can add tag to scope and root container. And register provider per tag.
289
-
290
- ```typescript
291
- import { composeDecorators } from "ts-constructor-injector";
292
- import { forKey, provider, Registration, asSingleton, perTags } from "ts-request-mediator";
293
-
294
- @forKey('IEngine')
295
- @provider(perTags('root'), asSingleton())
296
- class Logger {
297
- }
298
-
299
- @forKey('IEngine')
300
- @provider(perTags('home'), asSingleton())
301
- class Engine {
302
- constructor(@inject(by('ILogger')) private logger: ILogger) {
303
- }
304
- }
305
-
306
- const container = new Container(injector, { tags: ['root'] })
307
- .add(Registration.fromClass(Logger))
308
- .add(Registration.fromClass(Engine));
309
-
310
- const scope = container.createScope(['home', 'child']);
311
- const logger = scope.resolve('ILogger');
312
- scope.dispose();
313
- ```
314
-
315
- ## Container modules
316
-
317
- ```typescript
318
- import { Registration } from "ts-request-mediator";
319
-
320
- class Development implements IContainerModule {
321
- applyTo(container: IContainer): void {
322
- container.add(Registration.fromClass(DevLogger));
323
- }
324
- }
325
-
326
- class Production implements IContainerModule {
327
- applyTo(container: IContainer): void {
328
- container.add(Registration.fromClass(ProdLogger));
329
- }
330
- }
331
-
332
- const container = new Container(injector, { tags: ['root'] })
333
- .add(Registration.fromClass(Logger))
334
- .add(process.env.NODE_ENV === 'production' ? new Production() : new Development());
335
- ```
336
-
337
450
  ## Mocking / Tests
451
+ `AutoMockedContainer`. It will generate mocks for every dependency that you didn't define.
338
452
 
339
453
  ```typescript
340
454
  import {
341
455
  AutoMockedContainer,
342
456
  Container,
343
457
  DependencyKey,
344
- } from "ts-request-mediator";
458
+ } from "ts-ioc-container";
345
459
  import { Mock } from "moq.ts";
346
460
 
347
461
  export class MoqContainer extends AutoMockedContainer {
@@ -351,10 +465,6 @@ export class MoqContainer extends AutoMockedContainer {
351
465
  return this.resolveMock<T>(key).object();
352
466
  }
353
467
 
354
- dispose(): void {
355
- this.mocks.clear();
356
- }
357
-
358
468
  resolveMock<T>(key: DependencyKey): IMock<T> {
359
469
  if (!this.mocks.has(key)) {
360
470
  this.mocks.set(key, new Mock());
@@ -1,5 +1,5 @@
1
1
  import { DependencyKey, IContainer, IContainerModule, InjectionToken, Tag, Tagged } from './IContainer';
2
- import { IInjector } from '../IInjector';
2
+ import { IInjector } from '../injector/IInjector';
3
3
  import { IProvider } from '../provider/IProvider';
4
4
  export declare class Container implements IContainer, Tagged {
5
5
  private readonly injector;
package/cjs/index.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { IContainer, InjectionToken } from './container/IContainer';
2
1
  export { IContainer, Resolvable, IContainerModule, isDependencyKey, DependencyKey, InjectionToken, Tag, } from './container/IContainer';
3
2
  export { constructor } from './utils';
4
3
  export { Container } from './container/Container';
5
4
  export { ResolveDependency, IProvider } from './provider/IProvider';
6
- export { IInjector } from './IInjector';
5
+ export { IInjector } from './injector/IInjector';
7
6
  export { DependencyNotFoundError } from './container/DependencyNotFoundError';
8
7
  export { MethodNotImplementedError } from './container/MethodNotImplementedError';
9
8
  export { ContainerDisposedError } from './container/ContainerDisposedError';
@@ -14,4 +13,7 @@ export { perTags } from './provider/TaggedProvider';
14
13
  export { AutoMockedContainer } from './container/AutoMockedContainer';
15
14
  export { forKey, Registration } from './registration/Registration';
16
15
  export { DependencyMissingKeyError } from './registration/DependencyMissingKeyError';
17
- export declare const by: <T>(key: InjectionToken<T>, ...args: unknown[]) => (c: IContainer) => T;
16
+ export { ReflectionInjector, inject, by } from './injector/ReflectionInjector';
17
+ export { SimpleInjector } from './injector/SimpleInjector';
18
+ export { ProxyInjector } from './injector/ProxyInjector';
19
+ export { hook, getHooks } from './reflection';
package/cjs/index.js CHANGED
@@ -1,31 +1,6 @@
1
1
  "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
13
- }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
- if (ar || !(i in from)) {
21
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
- ar[i] = from[i];
23
- }
24
- }
25
- return to.concat(ar || Array.prototype.slice.call(from));
26
- };
27
2
  Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.by = exports.DependencyMissingKeyError = exports.Registration = exports.forKey = exports.AutoMockedContainer = exports.perTags = exports.asSingleton = exports.withArgs = exports.withArgsFn = exports.provider = exports.Provider = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.Container = exports.isDependencyKey = void 0;
3
+ exports.getHooks = exports.hook = exports.ProxyInjector = exports.SimpleInjector = exports.by = exports.inject = exports.ReflectionInjector = exports.DependencyMissingKeyError = exports.Registration = exports.forKey = exports.AutoMockedContainer = exports.perTags = exports.asSingleton = exports.withArgs = exports.withArgsFn = exports.provider = exports.Provider = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.Container = exports.isDependencyKey = void 0;
29
4
  var IContainer_1 = require("./container/IContainer");
30
5
  Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
31
6
  var Container_1 = require("./container/Container");
@@ -53,14 +28,15 @@ Object.defineProperty(exports, "forKey", { enumerable: true, get: function () {
53
28
  Object.defineProperty(exports, "Registration", { enumerable: true, get: function () { return Registration_1.Registration; } });
54
29
  var DependencyMissingKeyError_1 = require("./registration/DependencyMissingKeyError");
55
30
  Object.defineProperty(exports, "DependencyMissingKeyError", { enumerable: true, get: function () { return DependencyMissingKeyError_1.DependencyMissingKeyError; } });
56
- var by = function (key) {
57
- var args = [];
58
- for (var _i = 1; _i < arguments.length; _i++) {
59
- args[_i - 1] = arguments[_i];
60
- }
61
- return function (c) {
62
- return c.resolve.apply(c, __spreadArray([key], __read(args), false));
63
- };
64
- };
65
- exports.by = by;
31
+ var ReflectionInjector_1 = require("./injector/ReflectionInjector");
32
+ Object.defineProperty(exports, "ReflectionInjector", { enumerable: true, get: function () { return ReflectionInjector_1.ReflectionInjector; } });
33
+ Object.defineProperty(exports, "inject", { enumerable: true, get: function () { return ReflectionInjector_1.inject; } });
34
+ Object.defineProperty(exports, "by", { enumerable: true, get: function () { return ReflectionInjector_1.by; } });
35
+ var SimpleInjector_1 = require("./injector/SimpleInjector");
36
+ Object.defineProperty(exports, "SimpleInjector", { enumerable: true, get: function () { return SimpleInjector_1.SimpleInjector; } });
37
+ var ProxyInjector_1 = require("./injector/ProxyInjector");
38
+ Object.defineProperty(exports, "ProxyInjector", { enumerable: true, get: function () { return ProxyInjector_1.ProxyInjector; } });
39
+ var reflection_1 = require("./reflection");
40
+ Object.defineProperty(exports, "hook", { enumerable: true, get: function () { return reflection_1.hook; } });
41
+ Object.defineProperty(exports, "getHooks", { enumerable: true, get: function () { return reflection_1.getHooks; } });
66
42
  //# sourceMappingURL=index.js.map
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,qDAQgC;AAJ5B,6GAAA,eAAe,OAAA;AAMnB,mDAAkD;AAAzC,sGAAA,SAAS,OAAA;AAGlB,+EAA8E;AAArE,kIAAA,uBAAuB,OAAA;AAChC,mFAAkF;AAAzE,sIAAA,yBAAyB,OAAA;AAClC,6EAA4E;AAAnE,gIAAA,sBAAsB,OAAA;AAC/B,gDAAyD;AAAhD,oGAAA,QAAQ,OAAA;AAAE,oGAAA,QAAQ,OAAA;AAC3B,wDAAuE;AAAtD,0GAAA,UAAU,OAAA;AAAE,wGAAA,QAAQ,OAAA;AACrC,kEAA2D;AAAlD,gHAAA,WAAW,OAAA;AACpB,4DAAoD;AAA3C,yGAAA,OAAO,OAAA;AAChB,uEAAsE;AAA7D,0HAAA,mBAAmB,OAAA;AAC5B,4DAAmE;AAA1D,sGAAA,MAAM,OAAA;AAAE,4GAAA,YAAY,OAAA;AAC7B,sFAAqF;AAA5E,sIAAA,yBAAyB,OAAA;AAE3B,IAAM,EAAE,GACX,UAAI,GAAsB;IAAE,cAAkB;SAAlB,UAAkB,EAAlB,qBAAkB,EAAlB,IAAkB;QAAlB,6BAAkB;;IAC9C,OAAA,UAAC,CAAa;QACV,OAAA,CAAC,CAAC,OAAO,OAAT,CAAC,iBAAY,GAAG,UAAK,IAAI;IAAzB,CAA0B;AAD9B,CAC8B,CAAC;AAHtB,QAAA,EAAE,MAGoB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;AAAA,qDAQgC;AAJ5B,6GAAA,eAAe,OAAA;AAMnB,mDAAkD;AAAzC,sGAAA,SAAS,OAAA;AAGlB,+EAA8E;AAArE,kIAAA,uBAAuB,OAAA;AAChC,mFAAkF;AAAzE,sIAAA,yBAAyB,OAAA;AAClC,6EAA4E;AAAnE,gIAAA,sBAAsB,OAAA;AAC/B,gDAAyD;AAAhD,oGAAA,QAAQ,OAAA;AAAE,oGAAA,QAAQ,OAAA;AAC3B,wDAAuE;AAAtD,0GAAA,UAAU,OAAA;AAAE,wGAAA,QAAQ,OAAA;AACrC,kEAA2D;AAAlD,gHAAA,WAAW,OAAA;AACpB,4DAAoD;AAA3C,yGAAA,OAAO,OAAA;AAChB,uEAAsE;AAA7D,0HAAA,mBAAmB,OAAA;AAC5B,4DAAmE;AAA1D,sGAAA,MAAM,OAAA;AAAE,4GAAA,YAAY,OAAA;AAC7B,sFAAqF;AAA5E,sIAAA,yBAAyB,OAAA;AAClC,oEAA+E;AAAtE,wHAAA,kBAAkB,OAAA;AAAE,4GAAA,MAAM,OAAA;AAAE,wGAAA,EAAE,OAAA;AACvC,4DAA2D;AAAlD,gHAAA,cAAc,OAAA;AACvB,0DAAyD;AAAhD,8GAAA,aAAa,OAAA;AACtB,2CAA8C;AAArC,kGAAA,IAAI,OAAA;AAAE,sGAAA,QAAQ,OAAA"}