forked from typeorm/typeorm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontainer.ts
72 lines (59 loc) · 2.07 KB
/
container.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
/**
* Container options.
*/
export interface UseContainerOptions {
/**
* If set to true, then default container will be used in the case if given container haven't returned anything.
*/
fallback?: boolean;
/**
* If set to true, then default container will be used in the case if given container thrown an exception.
*/
fallbackOnErrors?: boolean;
}
export type ContainedType<T> = { new (...args: any[]): T } | Function;
export interface ContainerInterface {
get<T>(someClass: ContainedType<T>): T;
}
/**
* Container to be used by this library for inversion control. If container was not implicitly set then by default
* container simply creates a new instance of the given class.
*/
const defaultContainer: ContainerInterface = new (class implements ContainerInterface {
private instances: { type: Function, object: any }[] = [];
get<T>(someClass: ContainedType<T>): T {
let instance = this.instances.find(i => i.type === someClass);
if (!instance) {
instance = { type: someClass, object: new (someClass as new() => T)()};
this.instances.push(instance);
}
return instance.object;
}
})();
let userContainer: ContainerInterface;
let userContainerOptions: UseContainerOptions|undefined;
/**
* Sets container to be used by this library.
*/
export function useContainer(iocContainer: ContainerInterface, options?: UseContainerOptions) {
userContainer = iocContainer;
userContainerOptions = options;
}
/**
* Gets the IOC container used by this library.
*/
export function getFromContainer<T>(someClass: ContainedType<T>): T {
if (userContainer) {
try {
const instance = userContainer.get(someClass);
if (instance)
return instance;
if (!userContainerOptions || !userContainerOptions.fallback)
return instance;
} catch (error) {
if (!userContainerOptions || !userContainerOptions.fallbackOnErrors)
throw error;
}
}
return defaultContainer.get<T>(someClass);
}