Skip to content

Commit 1a79acb

Browse files
committed
feat(di): Add Module and Configuration decorators
1 parent d58602d commit 1a79acb

File tree

10 files changed

+111
-115
lines changed

10 files changed

+111
-115
lines changed

packages/di/src/class/Container.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export class Container extends LocalsContainer<Provider<any>> {
6868

6969
public addProviders(container: Map<TokenProvider, Provider<any>>) {
7070
container.forEach(provider => {
71-
if (!this.hasProvider(provider.provide)) {
71+
if (!this.hasProvider(provider.provide) && !provider.root) {
7272
this.setProvider(provider.provide, provider.clone());
7373
}
7474
});

packages/di/src/class/Provider.ts

+30-72
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,49 @@
1-
import {deepClone, Enumerable, getClass, getKeys, isClass, nameOf, NotEnumerable, Store, Type} from "@tsed/core";
1+
import {classOf, Enumerable, getKeys, isClass, nameOf, NotEnumerable, Store, Type} from "@tsed/core";
22
import {IDIConfigurationOptions, ProviderScope} from "../interfaces";
33
import {IProvider} from "../interfaces/IProvider";
44
import {ProviderType} from "../interfaces/ProviderType";
55
import {TokenProvider} from "../interfaces/TokenProvider";
66

77
export class Provider<T> implements IProvider<T> {
8-
/**
9-
*
10-
*/
8+
@Enumerable()
9+
public root: boolean = false;
10+
1111
@Enumerable()
1212
public type: ProviderType | any = ProviderType.PROVIDER;
13-
/**
14-
*
15-
*/
13+
1614
@Enumerable()
1715
public injectable: boolean = true;
18-
/**
19-
*
20-
*/
16+
2117
@Enumerable()
2218
public instance: T;
23-
/**
24-
*
25-
*/
19+
2620
@Enumerable()
2721
public deps: any[];
28-
/**
29-
*
30-
*/
22+
23+
@Enumerable()
24+
public imports: any[];
25+
3126
@Enumerable()
3227
public useFactory: Function;
3328

3429
@Enumerable()
3530
public useAsyncFactory: Function;
36-
/**
37-
*
38-
*/
31+
3932
@Enumerable()
4033
public useValue: any;
41-
/**
42-
*
43-
*/
34+
4435
@NotEnumerable()
4536
protected _provide: TokenProvider;
46-
/**
47-
*
48-
*/
37+
4938
@NotEnumerable()
5039
protected _useClass: Type<T>;
51-
/**
52-
*
53-
*/
40+
5441
@NotEnumerable()
5542
protected _instance: T;
56-
/**
57-
*
58-
*/
59-
@NotEnumerable()
60-
protected _scope: ProviderScope;
61-
/**
62-
*
63-
*/
43+
6444
@NotEnumerable()
6545
private _store: Store;
6646

67-
private _configuration: Partial<IDIConfigurationOptions>;
68-
6947
[key: string]: any;
7048

7149
constructor(token: TokenProvider) {
@@ -77,26 +55,17 @@ export class Provider<T> implements IProvider<T> {
7755
return this._provide;
7856
}
7957

80-
/**
81-
*
82-
* @returns {any}
83-
*/
8458
get provide(): TokenProvider {
8559
return this._provide;
8660
}
8761

88-
/**
89-
*
90-
* @param value
91-
*/
9262
set provide(value: TokenProvider) {
93-
this._provide = isClass(value) ? getClass(value) : value;
63+
if (value) {
64+
this._provide = isClass(value) ? classOf(value) : value;
65+
this._store = Store.from(value);
66+
}
9467
}
9568

96-
/**
97-
*
98-
* @returns {Type<T>}
99-
*/
10069
get useClass(): Type<T> {
10170
return this._useClass;
10271
}
@@ -108,30 +77,19 @@ export class Provider<T> implements IProvider<T> {
10877
@Enumerable()
10978
set useClass(value: Type<T>) {
11079
if (isClass(value)) {
111-
this._useClass = getClass(value);
80+
this._useClass = classOf(value);
11281
this._store = Store.from(value);
11382
}
11483
}
11584

116-
/**
117-
*
118-
* @returns {string}
119-
*/
12085
get className() {
12186
return this.name;
12287
}
12388

124-
/**
125-
*
126-
*/
12789
get name() {
12890
return nameOf(this.provide);
12991
}
13092

131-
/**
132-
*
133-
* @returns {Store}
134-
*/
13593
public get store(): Store {
13694
return this._store;
13795
}
@@ -150,7 +108,7 @@ export class Provider<T> implements IProvider<T> {
150108
return ProviderScope.SINGLETON;
151109
}
152110

153-
return this._store ? this.store.get("scope") : this._scope;
111+
return this.store.get("scope");
154112
}
155113

156114
/**
@@ -159,29 +117,29 @@ export class Provider<T> implements IProvider<T> {
159117
*/
160118
@Enumerable()
161119
set scope(scope: ProviderScope) {
162-
this._store ? this.store.set("scope", scope) : this._scope;
120+
this.store.set("scope", scope);
163121
}
164122

165123
get configuration(): Partial<IDIConfigurationOptions> {
166-
return this._configuration && deepClone(this._configuration);
124+
return this.store.get("configuration");
167125
}
168126

127+
@Enumerable()
169128
set configuration(configuration: Partial<IDIConfigurationOptions>) {
170-
this._configuration = configuration;
129+
this.store.set("configuration", configuration);
171130
}
172131

173132
isAsync(): boolean {
174133
return !!this.useAsyncFactory;
175134
}
176135

177-
/**
178-
*
179-
*/
180136
clone(): Provider<any> {
181-
const provider = new (getClass(this))(this.token);
137+
const provider = new (classOf(this))(this.token);
182138

183139
getKeys(this).forEach(key => {
184-
provider[key] = this[key];
140+
if (this[key] !== undefined) {
141+
provider[key] = this[key];
142+
}
185143
});
186144

187145
return provider;

packages/di/src/decorators/configuration.ts

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
1-
import {DecoratorParameters, getDecoratorType} from "@tsed/core";
2-
import {DIConfiguration, Inject} from "@tsed/di";
1+
import {DecoratorParameters, getDecoratorType, StoreSet} from "@tsed/core";
2+
import {Inject} from "../decorators/inject";
33
import {IDIConfigurationOptions} from "../interfaces/IDIConfigurationOptions";
4-
import {ProviderScope} from "../interfaces/ProviderScope";
5-
import {ProviderType} from "../interfaces/ProviderType";
6-
import {Injectable} from "./injectable";
4+
import {DIConfiguration} from "../services/DIConfiguration";
75

86
export type Configuration = IDIConfigurationOptions & DIConfiguration;
97

108
export function Configuration(configuration: Partial<IDIConfigurationOptions> = {}): Function {
119
return (...args: DecoratorParameters) => {
1210
switch (getDecoratorType(args, true)) {
1311
case "class":
14-
Injectable({
15-
type: ProviderType.PROVIDER,
16-
scope: ProviderScope.SINGLETON,
17-
configuration,
18-
injectable: false
19-
})(args[0]);
12+
StoreSet("configuration", configuration)(args[0]);
2013

2114
break;
2215
case "parameter.constructor":

packages/di/src/decorators/module.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {applyDecorators} from "@tsed/core";
2+
import {Injectable, ProviderType} from "@tsed/di";
3+
import {IDIConfigurationOptions} from "../interfaces/IDIConfigurationOptions";
4+
import {ProviderScope} from "../interfaces/ProviderScope";
5+
import {TokenProvider} from "../interfaces/TokenProvider";
6+
import {Configuration} from "./configuration";
7+
8+
export interface IModuleOptions extends IDIConfigurationOptions {
9+
/**
10+
* Define dependencies to build the provider
11+
*/
12+
imports?: TokenProvider[];
13+
/**
14+
*
15+
*/
16+
scope?: ProviderScope;
17+
18+
[key: string]: any;
19+
}
20+
21+
export function Module({imports, deps, root, scope, ...configuration}: Partial<IModuleOptions> = {}) {
22+
return applyDecorators(
23+
Configuration(configuration),
24+
Injectable({
25+
type: ProviderType.PROVIDER,
26+
scope: ProviderScope.SINGLETON,
27+
imports,
28+
deps,
29+
injectable: false,
30+
root
31+
})
32+
);
33+
}

packages/di/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export * from "./decorators/value";
1414
export * from "./decorators/intercept";
1515
export * from "./decorators/interceptor";
1616
export * from "./decorators/configuration";
17+
export * from "./decorators/module";
1718
export * from "./registries/ProviderRegistry";
1819
export * from "./registries/GlobalProviders";
1920
export * from "./services/InjectorService";

packages/di/src/interfaces/IInvokeOptions.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {TokenProvider} from "./TokenProvider";
33

44
export interface IInvokeOptions<T> {
55
deps: any[];
6+
imports: any[];
67
parent?: TokenProvider;
78
scope: ProviderScope;
89
useScope: boolean;

packages/di/src/interfaces/IProvider.ts

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {Type} from "@tsed/core";
22
import {ProviderScope} from "./ProviderScope";
33
import {ProviderType} from "./ProviderType";
44
import {TokenProvider} from "./TokenProvider";
5-
65
/**
76
*
87
*/

0 commit comments

Comments
 (0)