/
injectable.ts
79 lines (75 loc) · 2.27 KB
/
injectable.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
68
69
70
71
72
73
74
75
76
77
78
79
import { DiContainer, Type, TypeIdentifier } from "../di-container.ts";
import { Scope } from "../scope.ts";
import { Reflect } from "../shims/reflect.ts";
export type InjectableOptions =
| {
/**
* Determines the scope the service will be bound to.
*/
scope?: Scope;
/**
* Determines whether to make the service available globally. If false, the type must be set as a provider in a DI container.
*/
global?: boolean;
}
| {
/**
* Determines the scope the service will be bound to.
*/
scope: Scope.Custom;
/**
* For custom scopes, this value must be provided to act as identifier for a custom scope
*/
scopeIdentifier: unknown;
};
/**
* Decorator used to mark a type as available for dependency injection globally.
*
*/
export function Injectable(): ClassDecorator;
/**
* Decorator used to mark a type as available for dependency injection with options.
*/
export function Injectable(options: InjectableOptions): ClassDecorator;
/**
* Decorator used to mark a type as available for dependency injection using a identifier token
*/
export function Injectable(
identifier: TypeIdentifier,
options?: InjectableOptions,
): ClassDecorator;
export function Injectable(
identifierOrOptions?: TypeIdentifier | InjectableOptions,
options?: InjectableOptions,
): ClassDecorator {
// deno-lint-ignore ban-types
return function (target: Function) {
let identifier;
if (identifierOrOptions) {
if (isIdentifier(identifierOrOptions)) {
identifier = identifierOrOptions;
} else {
options = identifierOrOptions;
}
}
options = { scope: Scope.Injection, global: true, ...options };
let scope: Scope | string | undefined = options.scope;
if (scope === Scope.Custom) {
scope = (options as { scopeIdentifier: string }).scopeIdentifier;
}
if (identifier) {
DiContainer.root().registerAlias(target as Type, identifier);
}
if (options.global) {
DiContainer.root().registerFromMetadata(
target as Type,
Reflect.getMetadata("design:paramtypes", target),
undefined,
scope,
);
}
};
}
function isIdentifier(arg: unknown): arg is TypeIdentifier {
return typeof arg === "string" || typeof arg === "function";
}