/
instance-loader.ts
119 lines (105 loc) 路 3.82 KB
/
instance-loader.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { Logger, LoggerService } from '@nestjs/common';
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
import { Injectable } from '@nestjs/common/interfaces/injectable.interface';
import { MODULE_INIT_MESSAGE } from '../helpers/messages';
import { GraphInspector } from '../inspector/graph-inspector';
import { NestContainer } from './container';
import { Injector } from './injector';
import { InternalCoreModule } from './internal-core-module/internal-core-module';
import { Module } from './module';
export class InstanceLoader<TInjector extends Injector = Injector> {
constructor(
protected readonly container: NestContainer,
protected readonly injector: TInjector,
protected readonly graphInspector: GraphInspector,
private logger: LoggerService = new Logger(InstanceLoader.name, {
timestamp: true,
}),
) {}
public setLogger(logger: Logger) {
this.logger = logger;
}
public async createInstancesOfDependencies(
modules: Map<string, Module> = this.container.getModules(),
) {
this.createPrototypes(modules);
try {
await this.createInstances(modules);
} catch (err) {
this.graphInspector.inspectModules(modules);
this.graphInspector.registerPartial(err);
throw err;
}
this.graphInspector.inspectModules(modules);
}
private createPrototypes(modules: Map<string, Module>) {
modules.forEach(moduleRef => {
this.createPrototypesOfProviders(moduleRef);
this.createPrototypesOfInjectables(moduleRef);
this.createPrototypesOfControllers(moduleRef);
});
}
private async createInstances(modules: Map<string, Module>) {
await Promise.all(
[...modules.values()].map(async moduleRef => {
await this.createInstancesOfProviders(moduleRef);
await this.createInstancesOfInjectables(moduleRef);
await this.createInstancesOfControllers(moduleRef);
const { name } = moduleRef;
this.isModuleWhitelisted(name) &&
this.logger.log(MODULE_INIT_MESSAGE`${name}`);
}),
);
}
private createPrototypesOfProviders(moduleRef: Module) {
const { providers } = moduleRef;
providers.forEach(wrapper =>
this.injector.loadPrototype<Injectable>(wrapper, providers),
);
}
private async createInstancesOfProviders(moduleRef: Module) {
const { providers } = moduleRef;
const wrappers = [...providers.values()];
await Promise.all(
wrappers.map(async item => {
await this.injector.loadProvider(item, moduleRef);
this.graphInspector.inspectInstanceWrapper(item, moduleRef);
}),
);
}
private createPrototypesOfControllers(moduleRef: Module) {
const { controllers } = moduleRef;
controllers.forEach(wrapper =>
this.injector.loadPrototype<Controller>(wrapper, controllers),
);
}
private async createInstancesOfControllers(moduleRef: Module) {
const { controllers } = moduleRef;
const wrappers = [...controllers.values()];
await Promise.all(
wrappers.map(async item => {
await this.injector.loadController(item, moduleRef);
this.graphInspector.inspectInstanceWrapper(item, moduleRef);
}),
);
}
private createPrototypesOfInjectables(moduleRef: Module) {
const { injectables } = moduleRef;
injectables.forEach(wrapper =>
this.injector.loadPrototype(wrapper, injectables),
);
}
private async createInstancesOfInjectables(moduleRef: Module) {
const { injectables } = moduleRef;
const wrappers = [...injectables.values()];
await Promise.all(
wrappers.map(async item => {
await this.injector.loadInjectable(item, moduleRef);
this.graphInspector.inspectInstanceWrapper(item, moduleRef);
}),
);
}
private isModuleWhitelisted(name: string): boolean {
return name !== InternalCoreModule.name;
}
}