-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
/
inject.decorator.ts
67 lines (62 loc) 路 2.45 KB
/
inject.decorator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import {
PARAMTYPES_METADATA,
PROPERTY_DEPS_METADATA,
SELF_DECLARED_DEPS_METADATA,
} from '../../constants';
import { isUndefined } from '../../utils/shared.utils';
/**
* Decorator that marks a constructor parameter as a target for
* [Dependency Injection (DI)](https://docs.nestjs.com/providers#dependency-injection).
*
* Any injected provider must be visible within the module scope (loosely
* speaking, the containing module) of the class it is being injected into. This
* can be done by:
*
* - defining the provider in the same module scope
* - exporting the provider from one module scope and importing that module into the
* module scope of the class being injected into
* - exporting the provider from a module that is marked as global using the
* `@Global()` decorator
*
* #### Injection tokens
* Can be *types* (class names), *strings* or *symbols*. This depends on how the
* provider with which it is associated was defined. Providers defined with the
* `@Injectable()` decorator use the class name. Custom Providers may use strings
* or symbols as the injection token.
*
* @param token lookup key for the provider to be injected (assigned to the constructor
* parameter).
*
* @see [Providers](https://docs.nestjs.com/providers)
* @see [Custom Providers](https://docs.nestjs.com/fundamentals/custom-providers)
* @see [Injection Scopes](https://docs.nestjs.com/fundamentals/injection-scopes)
*
* @publicApi
*/
export function Inject<T = any>(
token?: T,
): PropertyDecorator & ParameterDecorator {
const injectCallHasArguments = arguments.length > 0;
return (target: object, key: string | symbol | undefined, index?: number) => {
let type = token || Reflect.getMetadata('design:type', target, key);
// Try to infer the token in a constructor-based injection
if (!type && !injectCallHasArguments) {
type = Reflect.getMetadata(PARAMTYPES_METADATA, target, key)?.[index];
}
if (!isUndefined(index)) {
let dependencies =
Reflect.getMetadata(SELF_DECLARED_DEPS_METADATA, target) || [];
dependencies = [...dependencies, { index, param: type }];
Reflect.defineMetadata(SELF_DECLARED_DEPS_METADATA, dependencies, target);
return;
}
let properties =
Reflect.getMetadata(PROPERTY_DEPS_METADATA, target.constructor) || [];
properties = [...properties, { key, type }];
Reflect.defineMetadata(
PROPERTY_DEPS_METADATA,
properties,
target.constructor,
);
};
}