ts-ioc-container 23.3.0 → 23.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -26
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ yarn add ts-ioc-container reflect-metadata
|
|
|
27
27
|
|
|
28
28
|
## Setup
|
|
29
29
|
### reflect-metadata
|
|
30
|
-
|
|
30
|
+
Just put it in the main file of your project. It should be first line of the code.
|
|
31
31
|
```typescript
|
|
32
32
|
import 'reflect-metadata';
|
|
33
33
|
```
|
|
@@ -42,11 +42,11 @@ import 'reflect-metadata';
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
## Container
|
|
46
|
-
|
|
45
|
+
## Container `IContainer`
|
|
46
|
+
It consists of 2 main parts:
|
|
47
47
|
|
|
48
|
-
-
|
|
49
|
-
-
|
|
48
|
+
- Providers - describes how to create instances of dependencies
|
|
49
|
+
- Injector - describes how to inject dependencies to constructor
|
|
50
50
|
|
|
51
51
|
### Basic usage
|
|
52
52
|
|
|
@@ -70,8 +70,9 @@ container.dispose();
|
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
### Scopes
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
Sometimes you need to create a scope of container. For example, when you want to create a scope per request in web application.
|
|
74
|
+
|
|
75
|
+
- NOTICE: when you create a scope of container then all providers are cloned to new scope. For that reason every provider has methods `clone` and `isValid` to clone itself and check if it's valid for certain scope. And every scope has method `hasTag` to check if it's valid for certain provider.
|
|
75
76
|
|
|
76
77
|
```typescript
|
|
77
78
|
import { Container, ReflectionInjector } from "ts-ioc-container";
|
|
@@ -81,10 +82,11 @@ const scope = container.createScope();
|
|
|
81
82
|
```
|
|
82
83
|
|
|
83
84
|
### Tags
|
|
85
|
+
Sometimes you want to mark some providers and resolve them only from certain scope.
|
|
84
86
|
|
|
85
|
-
- tag - is a string that can be used mark each container and scope
|
|
87
|
+
- tag - is a string that can be used to mark each container and scope
|
|
86
88
|
- 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
|
|
89
|
+
- NOTICE: when you create a scope then we clone ONLY tags-matched providers.
|
|
88
90
|
|
|
89
91
|
```typescript
|
|
90
92
|
import { Container, perTags, ReflectionInjector } from "ts-ioc-container";
|
|
@@ -96,6 +98,8 @@ scope.resolve('ILogger'); // it will be resolved from container, not from scope
|
|
|
96
98
|
```
|
|
97
99
|
|
|
98
100
|
### Instances
|
|
101
|
+
Sometimes you want to get all instances from container and its scopes. For example, when you want to dispose all instances of container.
|
|
102
|
+
|
|
99
103
|
- you can get instances from container and scope which were created by injector
|
|
100
104
|
|
|
101
105
|
```typescript
|
|
@@ -112,6 +116,8 @@ expect(container.getInstances().length).toBe(2);
|
|
|
112
116
|
```
|
|
113
117
|
|
|
114
118
|
### Disposing
|
|
119
|
+
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.
|
|
120
|
+
|
|
115
121
|
- container can be disposed
|
|
116
122
|
- when container is disposed then all scopes are disposed too
|
|
117
123
|
- when container is disposed then it unregisters all providers and remove all instances
|
|
@@ -130,12 +136,15 @@ expect(() => container.resolve('ILogger')).toThrow(ContainerDisposedError);
|
|
|
130
136
|
expect(container.getInstances().length).toBe(0);
|
|
131
137
|
```
|
|
132
138
|
|
|
133
|
-
## Injectors
|
|
139
|
+
## Injectors `IInjector`
|
|
140
|
+
Injectors are used to describe how dependencies should be injected to constructor.
|
|
141
|
+
|
|
134
142
|
- `ReflectionInjector` - injects dependencies using `@inject` decorator
|
|
135
143
|
- `ProxyInjector` - injects dependencies as dictionary `Record<string, unknown>`
|
|
136
144
|
- `SimpleInjector` - just passes container to constructor with others arguments
|
|
137
145
|
|
|
138
146
|
### Reflection injector
|
|
147
|
+
This type of injector uses `@inject` decorator to mark where dependencies should be injected. It's bases on `reflect-metadata` package. That's why I call it `ReflectionInjector`.
|
|
139
148
|
|
|
140
149
|
```typescript
|
|
141
150
|
import { Container, IContainer, IInjector, Provider, by, inject, resolve } from "ts-ioc-container";
|
|
@@ -167,6 +176,7 @@ app.run();
|
|
|
167
176
|
```
|
|
168
177
|
|
|
169
178
|
### Simple injector
|
|
179
|
+
This type of injector just passes container to constructor with others arguments.
|
|
170
180
|
|
|
171
181
|
```typescript
|
|
172
182
|
import { SimpleInjector, IContainer } from "ts-ioc-container";
|
|
@@ -197,6 +207,7 @@ app.run();
|
|
|
197
207
|
```
|
|
198
208
|
|
|
199
209
|
### Proxy injector
|
|
210
|
+
This type of injector injects dependencies as dictionary `Record<string, unknown>`.
|
|
200
211
|
|
|
201
212
|
```typescript
|
|
202
213
|
import { ProxyInjector, IContainer } from "ts-ioc-container";
|
|
@@ -226,9 +237,13 @@ const app = container.resolve(App);
|
|
|
226
237
|
app.run();
|
|
227
238
|
```
|
|
228
239
|
|
|
229
|
-
## Providers
|
|
230
|
-
|
|
240
|
+
## Providers `IProvider<T>`
|
|
241
|
+
Providers are used to describe how instances should be created. It has next basic methods:
|
|
242
|
+
- `resolve` - creates instance with passed arguments
|
|
243
|
+
- `clone` - we invoke it when we create a scope. It clones provider to new scope.
|
|
244
|
+
- `isValid` - checks if provider can be resolved from container or cloned to container with certain tags
|
|
231
245
|
|
|
246
|
+
There are next types of providers:
|
|
232
247
|
- `Provider` - basic provider
|
|
233
248
|
- `SingletonProvider` - provider that creates only one instance in every scope where it's resolved
|
|
234
249
|
- `TaggedProvider` - provider that can be resolved only from container with certain tags and their sub scopes
|
|
@@ -279,6 +294,7 @@ container.register('ILogger', Provider.fromClass(Logger));
|
|
|
279
294
|
```
|
|
280
295
|
|
|
281
296
|
### Singleton provider
|
|
297
|
+
Sometimes you need to create only one instance of dependency per scope. For example, you want to create only one logger per scope.
|
|
282
298
|
|
|
283
299
|
- Singleton provider creates only one instance in every scope where it's resolved.
|
|
284
300
|
- NOTICE: if you create a scope 'A' of container 'root' then Logger of A !== Logger of root.
|
|
@@ -298,8 +314,8 @@ container.resolve('ILogger') !== scope.resolve('ILogger'); // true. NOTICE: beca
|
|
|
298
314
|
```
|
|
299
315
|
|
|
300
316
|
### Tagged provider
|
|
301
|
-
|
|
302
|
-
It doesn't make
|
|
317
|
+
Sometimes you need to resolve provider only from container with certain tags and their sub scopes. Especially if you want to register dependency as singleton for some tags, for example `root`
|
|
318
|
+
- NOTICE: It doesn't make clones in not tagged-matched scopes. Usually it's used with `SingletonProvider`.
|
|
303
319
|
|
|
304
320
|
```typescript
|
|
305
321
|
import { Provider, TaggedProvider, asSingleton, perTags } from "ts-ioc-container";
|
|
@@ -318,7 +334,7 @@ container.resolve('ILogger') === scope.resolve('ILogger'); // true
|
|
|
318
334
|
```
|
|
319
335
|
|
|
320
336
|
### Args provider
|
|
321
|
-
|
|
337
|
+
Sometimes you want to bind some arguments to provider. This is what `ArgsProvider` is for.
|
|
322
338
|
- NOTICE: args from this provider has higher priority than args from `resolve` method.
|
|
323
339
|
|
|
324
340
|
```typescript
|
|
@@ -341,8 +357,7 @@ container.resolve('ILogger', 'Main').name === 'Main'; // true
|
|
|
341
357
|
```
|
|
342
358
|
|
|
343
359
|
## Container modules
|
|
344
|
-
|
|
345
|
-
if you want to encapsulate some logic to enrich container you can use `IContainerModule`.
|
|
360
|
+
Sometimes you want to encapsulate registration logic in separate module. This is what `IContainerModule` is for.
|
|
346
361
|
|
|
347
362
|
```typescript
|
|
348
363
|
import { Registration } from "ts-ioc-container";
|
|
@@ -365,7 +380,7 @@ const container = new Container(injector, { tags: ['root'] })
|
|
|
365
380
|
```
|
|
366
381
|
|
|
367
382
|
## Registration module (Provider + DependencyKey)
|
|
368
|
-
|
|
383
|
+
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.
|
|
369
384
|
|
|
370
385
|
```typescript
|
|
371
386
|
import { asSingleton, perTags, forKey, Registration, Provider } from "ts-ioc-container";
|
|
@@ -393,7 +408,7 @@ container.register('ILogger', Provider.fromClass(Logger));
|
|
|
393
408
|
```
|
|
394
409
|
|
|
395
410
|
## Hooks
|
|
396
|
-
|
|
411
|
+
Sometimes you need to invoke methods after construct or dispose of class. This is what hooks are for.
|
|
397
412
|
|
|
398
413
|
```typescript
|
|
399
414
|
import {
|
|
@@ -406,9 +421,6 @@ import {
|
|
|
406
421
|
hook,
|
|
407
422
|
} from "ts-ioc-container";
|
|
408
423
|
|
|
409
|
-
const onConstruct = hook('onConstruct');
|
|
410
|
-
const onDispose = hook('onDispose');
|
|
411
|
-
|
|
412
424
|
class MyInjector implements IInjector {
|
|
413
425
|
private injector = new ReflectionInjector();
|
|
414
426
|
|
|
@@ -424,12 +436,12 @@ class MyInjector implements IInjector {
|
|
|
424
436
|
|
|
425
437
|
@forKey('ILogger')
|
|
426
438
|
class Logger {
|
|
427
|
-
@hook('
|
|
439
|
+
@hook('onConstruct')
|
|
428
440
|
initialize() {
|
|
429
441
|
console.log('initialized');
|
|
430
442
|
}
|
|
431
443
|
|
|
432
|
-
@hook('
|
|
444
|
+
@hook('onDispose')
|
|
433
445
|
dispose() {
|
|
434
446
|
console.log('disposed');
|
|
435
447
|
}
|
|
@@ -447,8 +459,8 @@ for (const instance of container.getInstances()) {
|
|
|
447
459
|
}
|
|
448
460
|
```
|
|
449
461
|
|
|
450
|
-
## Mocking / Tests
|
|
451
|
-
|
|
462
|
+
## Mocking / Tests `AutoMockedContainer`
|
|
463
|
+
Sometimes you need to automatically mock all dependencies in container. This is what `AutoMockedContainer` is for.
|
|
452
464
|
|
|
453
465
|
```typescript
|
|
454
466
|
import {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "23.3.
|
|
3
|
+
"version": "23.3.2",
|
|
4
4
|
"description": "Typescript IoC container",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"ts-jest": "27.0.5",
|
|
53
53
|
"typescript": "4.4.3"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "8734c4ffb51b8544f037ec2aedb76567579e9e39"
|
|
56
56
|
}
|