-
Notifications
You must be signed in to change notification settings - Fork 818
/
Copy pathcontainer.ts
59 lines (52 loc) · 1.87 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
/**
* 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;
}
/**
* 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: { get<T>(someClass: { new (...args: any[]): T } | Function): T } = new (class {
private instances: { type: Function; object: any }[] = [];
get<T>(someClass: { new (...args: any[]): T }): T {
let instance = this.instances.find(instance => instance.type === someClass);
if (!instance) {
instance = { type: someClass, object: new someClass() };
this.instances.push(instance);
}
return instance.object;
}
})();
let userContainer: { get<T>(someClass: { new (...args: any[]): T } | Function): T };
let userContainerOptions: UseContainerOptions;
/**
* Sets container to be used by this library.
*/
export function useContainer(iocContainer: { get(someClass: any): any }, options?: UseContainerOptions): void {
userContainer = iocContainer;
userContainerOptions = options;
}
/**
* Gets the IOC container used by this library.
*/
export function getFromContainer<T>(someClass: { new (...args: any[]): T } | Function): 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);
}