@adimm/x-injection 0.5.1 → 0.6.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.
- package/README.md +123 -4
- package/dist/index.cjs +184 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +468 -445
- package/dist/index.d.ts +468 -445
- package/dist/index.js +164 -129
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<h1 align="center">
|
|
2
|
-
xInjection <a href="https://www.npmjs.com/package/@adimm/x-injection" target="__blank" alt="Release Version"><img src="https://
|
|
3
|
-
<img src="https://
|
|
2
|
+
xInjection <a href="https://www.npmjs.com/package/@adimm/x-injection" target="__blank" alt="Release Version"><img src="https://badgen.net/npm/v/@adimm/x-injection"></a>
|
|
3
|
+
<img src="https://badgen.net/npm/license/@adimm/x-injection" alt="License">
|
|
4
|
+
<a href="https://app.codecov.io/gh/AdiMarianMutu/x-injection" target="__blank" alt="Release Version"><img src="https://badgen.net/codecov/c/github/AdiMarianMutu/x-injection"></a>
|
|
4
5
|
</h1>
|
|
5
6
|
|
|
6
7
|
<p align="center">
|
|
7
8
|
<a href="https://github.com/AdiMarianMutu/x-injection/actions/workflows/ci.yml?query=branch%3Amain" target="__blank"><img src="https://github.com/AdiMarianMutu/x-injection/actions/workflows/ci.yml/badge.svg?branch=main"></a>
|
|
8
9
|
<a href="https://github.com/AdiMarianMutu/x-injection/actions/workflows/publish.yml" target="__blank"><img src="https://github.com/AdiMarianMutu/x-injection/actions/workflows/publish.yml/badge.svg"></a>
|
|
9
10
|
<br>
|
|
10
|
-
<img src="https://
|
|
11
|
-
<a href="https://www.npmjs.com/package/@adimm/x-injection" target="__blank" alt="Monthly Downloads"><img src="https://
|
|
11
|
+
<img src="https://badgen.net/bundlephobia/minzip/@adimm/x-injection">
|
|
12
|
+
<a href="https://www.npmjs.com/package/@adimm/x-injection" target="__blank" alt="Monthly Downloads"><img src="https://badgen.net/npm/dm/@adimm/x-injection"></a>
|
|
12
13
|
</p>
|
|
13
14
|
|
|
14
15
|
## Table of Contents
|
|
@@ -21,10 +22,15 @@ xInjection <a href="https://www.npmjs.com/package/@adimm/x-injection" targe
|
|
|
21
22
|
- [Getting Started](#getting-started)
|
|
22
23
|
- [Bootstrapping the AppModule](#bootstrapping-the-appmodule)
|
|
23
24
|
- [Registering Global Providers](#registering-global-providers)
|
|
25
|
+
- [Registering Global Modules](#registering-global-modules)
|
|
24
26
|
- [Injection Scope](#injection-scope)
|
|
27
|
+
- [Singleton](#singleton)
|
|
28
|
+
- [Transient](#transient)
|
|
29
|
+
- [Request](#request)
|
|
25
30
|
- [Custom Provider Modules](#custom-provider-modules)
|
|
26
31
|
- [Dynamic Exports](#dynamic-exports)
|
|
27
32
|
- [Advanced Usage](#advanced-usage)
|
|
33
|
+
- [Unit Tests](#unit-tests)
|
|
28
34
|
- [Documentation](#documentation)
|
|
29
35
|
- [ReactJS Implementation](#reactjs-implementation)
|
|
30
36
|
- [Contributing](#contributing)
|
|
@@ -106,6 +112,29 @@ AppModule.register({
|
|
|
106
112
|
|
|
107
113
|
Now, `LoggerService` and `ConfigService` can be injected anywhere in your app, including inside all `ProviderModules`.
|
|
108
114
|
|
|
115
|
+
### Registering Global Modules
|
|
116
|
+
|
|
117
|
+
You can also import entire modules into the `AppModule` like so:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
const ConfigModule = new ProviderModule({
|
|
121
|
+
identifier: Symbol('ConfigModule'),
|
|
122
|
+
markAsGlobal: true,
|
|
123
|
+
providers: [
|
|
124
|
+
{ provide: 'SECRET_TOKEN', useValue: '123' },
|
|
125
|
+
{ provide: 'SECRET_TOKEN_2', useValue: 123 },
|
|
126
|
+
],
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
AppModule.register({
|
|
130
|
+
imports: [ConfigModule],
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
> **Note:** _All modules which are imported into the `AppModule` must have the [markAsGlobal](https://adimarianmutu.github.io/x-injection/interfaces/ProviderModuleOptions.html#markAsGlobal) option set to `true`, otherwise the [InjectionProviderModuleGlobalMarkError](https://adimarianmutu.github.io/x-injection/classes/InjectionProviderModuleGlobalMarkError.html) exception will be thrown!_
|
|
135
|
+
>
|
|
136
|
+
> **Note2:** _An [InjectionProviderModuleGlobalMarkError](https://adimarianmutu.github.io/x-injection/classes/InjectionProviderModuleGlobalMarkError.html) exception will be thrown also when importing into the `AppModule` a module which does **not** have the [markAsGlobal](https://adimarianmutu.github.io/x-injection/interfaces/ProviderModuleOptions.html#markAsGlobal) flag option!_
|
|
137
|
+
|
|
109
138
|
### Injection Scope
|
|
110
139
|
|
|
111
140
|
There are mainly 3 first-class ways to set the [InjectionScope](https://adimarianmutu.github.io/x-injection/enums/InjectionScope.html) of a provider, and each one has an order priority.
|
|
@@ -134,6 +163,54 @@ The below list shows them in order of priority _(highest to lowest)_, meaning th
|
|
|
134
163
|
|
|
135
164
|
> **Note:** _Imported modules/providers retain their original `InjectionScope`!_
|
|
136
165
|
|
|
166
|
+
#### Singleton
|
|
167
|
+
|
|
168
|
+
The [Singleton](https://adimarianmutu.github.io/x-injection/enums/InjectionScope.html#singleton) injection scope means that once a dependency has been resolved from within a module will be cached and further resolutions will use the value from the cache.
|
|
169
|
+
|
|
170
|
+
Example:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
expect(MyModule.get(MyProvider)).toBe(MyModule.get(MyProvider));
|
|
174
|
+
// true
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Transient
|
|
178
|
+
|
|
179
|
+
The [Singleton](https://adimarianmutu.github.io/x-injection/enums/InjectionScope.html#transient) injection scope means that a _new_ instance of the dependency will be used whenever a resolution occurs.
|
|
180
|
+
|
|
181
|
+
Example:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
expect(MyModule.get(MyProvider)).toBe(MyModule.get(MyProvider));
|
|
185
|
+
// false
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Request
|
|
189
|
+
|
|
190
|
+
The [Request](https://adimarianmutu.github.io/x-injection/enums/InjectionScope.html#request) injection scope means that the _same_ instance will be used when a resolution happens in the _same_ request scope.
|
|
191
|
+
|
|
192
|
+
Example:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
class Book {}
|
|
196
|
+
|
|
197
|
+
class Box {
|
|
198
|
+
constructor(
|
|
199
|
+
private readonly book0: Book,
|
|
200
|
+
private readonly book1: Book
|
|
201
|
+
) {}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const box0 = MyModule.get(Box);
|
|
205
|
+
const box1 = MyModule.get(Box);
|
|
206
|
+
|
|
207
|
+
expect(box0.book0).toBe(box0.book1);
|
|
208
|
+
// true
|
|
209
|
+
|
|
210
|
+
expect(box0.book0).toBe(box1.book0);
|
|
211
|
+
// false
|
|
212
|
+
```
|
|
213
|
+
|
|
137
214
|
## Custom Provider Modules
|
|
138
215
|
|
|
139
216
|
You can define custom modules to encapsulate related providers and manage their scope:
|
|
@@ -304,6 +381,48 @@ const globalContainer = GlobalContainer || AppModule.toNaked().container;
|
|
|
304
381
|
|
|
305
382
|
For advanced scenarios, `IProviderModuleNaked` exposes additional methods (prefixed with `__`) that wrap InversifyJS APIs, supporting native `xInjection` provider tokens and more.
|
|
306
383
|
|
|
384
|
+
## Unit Tests
|
|
385
|
+
|
|
386
|
+
It is very easy to create mock modules so you can use them in your unit tests.
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
class ApiService {
|
|
390
|
+
constructor(private readonly userService: UserService) {}
|
|
391
|
+
|
|
392
|
+
async sendRequest<T>(location: LocationParams): Promise<T> {
|
|
393
|
+
// Pseudo Implementation
|
|
394
|
+
return this.sendToLocation(user, location);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
private async sendToLocation(user: User, location: any): Promise<any> {}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const ApiModule = new ProviderModule({
|
|
401
|
+
identifier: Symbol('ApiModule'),
|
|
402
|
+
providers: [UserService, ApiService],
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
const ApiModuleMocked = new ProviderModule({
|
|
406
|
+
identifier: Symbol('ApiModule_MOCK'),
|
|
407
|
+
providers: [
|
|
408
|
+
{
|
|
409
|
+
provide: UserService,
|
|
410
|
+
useClass: UserService_Mock,
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
provide: ApiService,
|
|
414
|
+
useValue: {
|
|
415
|
+
sendRequest: async (location) => {
|
|
416
|
+
console.log(location);
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
});
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Now what you have to do is just to provide the `ApiModuleMocked` instead of the `ApiModule` 😎
|
|
425
|
+
|
|
307
426
|
## Documentation
|
|
308
427
|
|
|
309
428
|
Comprehensive, auto-generated documentation is available at:
|