-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
auto-injectable.ts
43 lines (40 loc) · 1.44 KB
/
auto-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
import constructor from "../types/constructor.ts";
import { getParamInfo } from "../reflection-helpers.ts";
import { instance as globalContainer } from "../dependency-container.ts";
import { isTokenDescriptor } from "../providers/injection-token.ts";
import { formatErrorCtor } from "../error-helpers.ts";
/**
* Class decorator factory that replaces the decorated class' constructor with
* a parameter less constructor that has dependencies auto-resolved
*
* Note: Resolution is performed using the global container
*
* @return {Function} The class decorator
*/
function autoInjectable(): (target: constructor<any>) => any {
return function (target: constructor<any>): constructor<any> {
const paramInfo = getParamInfo(target);
return class extends target {
constructor(...args: any[]) {
super(
...args.concat(
paramInfo.slice(args.length).map((type, index) => {
try {
if (isTokenDescriptor(type)) {
return type.multiple
? globalContainer.resolveAll(type.token)
: globalContainer.resolve(type.token);
}
return globalContainer.resolve(type);
} catch (e) {
const argIndex = index + args.length;
throw new Error(formatErrorCtor(target, argIndex, e));
}
}),
),
);
}
};
};
}
export default autoInjectable;