@zk-tech/bedrock 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/container-factory/index.cjs +254 -0
- package/dist/container-factory/index.cjs.map +1 -0
- package/dist/container-factory/index.d.cts +32 -0
- package/dist/container-factory/index.d.ts +32 -0
- package/dist/container-factory/index.js +232 -0
- package/dist/container-factory/index.js.map +1 -0
- package/dist/di/index.d.cts +7 -95
- package/dist/di/index.d.ts +7 -95
- package/dist/dynamic-dependency-service.interface-BrwqELkH.d.ts +40 -0
- package/dist/dynamic-dependency-service.interface-OUOyz9BD.d.cts +40 -0
- package/dist/instantiation-service-DjBf8Dy1.d.cts +59 -0
- package/dist/instantiation-service-V9JO6Ljg.d.ts +59 -0
- package/dist/{instantiation-service.interface-CVFMBUUD.d.cts → instantiation-service.interface-bshqO0aS.d.cts} +1 -1
- package/dist/{instantiation-service.interface-CVFMBUUD.d.ts → instantiation-service.interface-bshqO0aS.d.ts} +1 -1
- package/dist/launch/index.d.cts +1 -1
- package/dist/launch/index.d.ts +1 -1
- package/dist/services/dynamic-dependency/index.cjs +1583 -0
- package/dist/services/dynamic-dependency/index.cjs.map +1 -0
- package/dist/services/dynamic-dependency/index.d.cts +17 -0
- package/dist/services/dynamic-dependency/index.d.ts +17 -0
- package/dist/services/dynamic-dependency/index.js +1581 -0
- package/dist/services/dynamic-dependency/index.js.map +1 -0
- package/dist/type-BsqwDzaj.d.cts +39 -0
- package/dist/type-Bya55PZP.d.ts +39 -0
- package/package.json +1 -1
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lodash_es_star = require('lodash-es');
|
|
4
|
+
|
|
5
|
+
function _interopNamespace(e) {
|
|
6
|
+
if (e && e.__esModule) return e;
|
|
7
|
+
var n = Object.create(null);
|
|
8
|
+
if (e) {
|
|
9
|
+
Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default') {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
n.default = e;
|
|
20
|
+
return Object.freeze(n);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var lodash_es_star__namespace = /*#__PURE__*/_interopNamespace(lodash_es_star);
|
|
24
|
+
|
|
25
|
+
var __defProp = Object.defineProperty;
|
|
26
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
27
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
28
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
29
|
+
var __copyProps = (to, from, except, desc) => {
|
|
30
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
31
|
+
for (let key of __getOwnPropNames(from))
|
|
32
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
33
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
34
|
+
}
|
|
35
|
+
return to;
|
|
36
|
+
};
|
|
37
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget);
|
|
38
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
39
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
40
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
41
|
+
if (decorator = decorators[i])
|
|
42
|
+
result = (decorator(result)) || result;
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
46
|
+
|
|
47
|
+
// src/container-factory/generate-register-lazy-service-task.ts
|
|
48
|
+
function generateRegisterLazyServiceTask(registry, containerService, identifier) {
|
|
49
|
+
return containerService.invokeFunction((servicesAccessor) => {
|
|
50
|
+
const lazyService = servicesAccessor.get(identifier.lazy);
|
|
51
|
+
return new Promise(async (resolve, reject) => {
|
|
52
|
+
try {
|
|
53
|
+
const instance = await lazyService.getInstance();
|
|
54
|
+
registry.registerInstance(identifier.real, instance);
|
|
55
|
+
resolve();
|
|
56
|
+
} catch (err) {
|
|
57
|
+
reject(err);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/lodash-es/index.ts
|
|
64
|
+
var lodash_es_exports = {};
|
|
65
|
+
__reExport(lodash_es_exports, lodash_es_star__namespace);
|
|
66
|
+
|
|
67
|
+
// src/di/base.ts
|
|
68
|
+
var serviceIds = /* @__PURE__ */ new Map();
|
|
69
|
+
var DI_TARGET = "$di$target";
|
|
70
|
+
var DI_DEPENDENCIES = "$di$dependencies";
|
|
71
|
+
function setServiceDependency(id, ctor, index) {
|
|
72
|
+
if (ctor[DI_TARGET] === ctor) {
|
|
73
|
+
ctor[DI_DEPENDENCIES].push({ id, index });
|
|
74
|
+
} else {
|
|
75
|
+
ctor[DI_DEPENDENCIES] = [{ id, index }];
|
|
76
|
+
ctor[DI_TARGET] = ctor;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function createDecorator(serviceId) {
|
|
80
|
+
if (serviceIds.has(serviceId)) {
|
|
81
|
+
return serviceIds.get(serviceId);
|
|
82
|
+
}
|
|
83
|
+
const id = function(target, key, index) {
|
|
84
|
+
if (arguments.length !== 3) {
|
|
85
|
+
throw new Error("@IServiceName-decorator can only be used to decorate a parameter");
|
|
86
|
+
}
|
|
87
|
+
setServiceDependency(id, target, index);
|
|
88
|
+
};
|
|
89
|
+
id.toString = () => serviceId;
|
|
90
|
+
serviceIds.set(serviceId, id);
|
|
91
|
+
return id;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/di/descriptor.ts
|
|
95
|
+
var SyncDescriptor = class {
|
|
96
|
+
constructor(ctor, staticArguments = [], supportsDelayedInstantiation = false) {
|
|
97
|
+
this.ctor = ctor;
|
|
98
|
+
this.staticArguments = staticArguments;
|
|
99
|
+
this.supportsDelayedInstantiation = supportsDelayedInstantiation;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// src/di/instantiation-service.interface.ts
|
|
104
|
+
var IInstantiationService = createDecorator("instantiation");
|
|
105
|
+
|
|
106
|
+
// src/assert/assert.ts
|
|
107
|
+
function abort(reason) {
|
|
108
|
+
throw new Error(`lvAssert(${reason})`);
|
|
109
|
+
}
|
|
110
|
+
function lvAssert(expr, reason) {
|
|
111
|
+
if (!expr) {
|
|
112
|
+
abort(reason ?? "#expr is false");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/di/service-ownership-collection.ts
|
|
117
|
+
var ServiceOwnershipCollection = class {
|
|
118
|
+
constructor(...entries) {
|
|
119
|
+
this._entries = /* @__PURE__ */ new Map();
|
|
120
|
+
for (const [id, service] of entries) {
|
|
121
|
+
this.set(id, service);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
get entries() {
|
|
125
|
+
return this._entries;
|
|
126
|
+
}
|
|
127
|
+
set(id, ownership) {
|
|
128
|
+
this._entries.set(id, ownership);
|
|
129
|
+
}
|
|
130
|
+
has(id) {
|
|
131
|
+
return this._entries.has(id);
|
|
132
|
+
}
|
|
133
|
+
get(id) {
|
|
134
|
+
return this._entries.get(id);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// src/di/service-collection.ts
|
|
139
|
+
var ServiceCollection = class {
|
|
140
|
+
constructor(options) {
|
|
141
|
+
this._entries = /* @__PURE__ */ new Map();
|
|
142
|
+
for (const [id, service] of options?.entries || []) {
|
|
143
|
+
this.set(id, service);
|
|
144
|
+
}
|
|
145
|
+
if (options?.ownership) {
|
|
146
|
+
this._ownership = options.ownership;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
get entries() {
|
|
150
|
+
return this._entries;
|
|
151
|
+
}
|
|
152
|
+
get ownerships() {
|
|
153
|
+
return this._ownership?.entries;
|
|
154
|
+
}
|
|
155
|
+
set(id, instanceOrDescriptor) {
|
|
156
|
+
this._entries.set(id, instanceOrDescriptor);
|
|
157
|
+
}
|
|
158
|
+
has(id) {
|
|
159
|
+
return this._entries.has(id);
|
|
160
|
+
}
|
|
161
|
+
get(id) {
|
|
162
|
+
return this._entries.get(id);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// src/di/service-registry.ts
|
|
167
|
+
var ServiceRegistry = class {
|
|
168
|
+
constructor(config = {}) {
|
|
169
|
+
this._registry = [];
|
|
170
|
+
this._serviceOwnership = new ServiceOwnershipCollection();
|
|
171
|
+
// 重复检测的id记录
|
|
172
|
+
this._ids = /* @__PURE__ */ new Set();
|
|
173
|
+
this._checkDuplicate = config.checkDuplicate ?? false;
|
|
174
|
+
}
|
|
175
|
+
get registry() {
|
|
176
|
+
return this._registry;
|
|
177
|
+
}
|
|
178
|
+
register(id, ctorOrDescriptor, supportsDelayedInstantiation) {
|
|
179
|
+
if (!(ctorOrDescriptor instanceof SyncDescriptor)) {
|
|
180
|
+
ctorOrDescriptor = new SyncDescriptor(
|
|
181
|
+
ctorOrDescriptor,
|
|
182
|
+
[],
|
|
183
|
+
Boolean(supportsDelayedInstantiation)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
if (this._checkDuplicate) {
|
|
187
|
+
lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);
|
|
188
|
+
this._ids.add(id.toString());
|
|
189
|
+
}
|
|
190
|
+
this._registry.push([id, ctorOrDescriptor]);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* 直接注册一个服务的实例
|
|
194
|
+
*
|
|
195
|
+
* 注意:谨慎使用,优先使用register
|
|
196
|
+
* 一般用于特殊场景:需要先于DI之前就构造了某个service
|
|
197
|
+
*/
|
|
198
|
+
registerInstance(id, instance, options) {
|
|
199
|
+
if (this._checkDuplicate) {
|
|
200
|
+
lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);
|
|
201
|
+
this._ids.add(id.toString());
|
|
202
|
+
}
|
|
203
|
+
this._registry.push([id, instance]);
|
|
204
|
+
this._serviceOwnership.set(id, options?.ownership ?? 1 /* Owned */);
|
|
205
|
+
}
|
|
206
|
+
makeCollection() {
|
|
207
|
+
const serviceCollection = new ServiceCollection({
|
|
208
|
+
ownership: this._serviceOwnership
|
|
209
|
+
});
|
|
210
|
+
for (const [id, instanceOrDescriptor] of this.registry) {
|
|
211
|
+
serviceCollection.set(id, instanceOrDescriptor);
|
|
212
|
+
}
|
|
213
|
+
return serviceCollection;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// src/services/dynamic-dependency/dynamic-dependency-service.interface.ts
|
|
218
|
+
var IDynamicDependencyService = createDecorator(
|
|
219
|
+
"dynamic-dependency-service"
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
// src/container-factory/abstract-container-factory.ts
|
|
223
|
+
exports.AbstractContainerFactory = class AbstractContainerFactory {
|
|
224
|
+
constructor(_parentContainerService, _dynamicDependencyService) {
|
|
225
|
+
this._parentContainerService = _parentContainerService;
|
|
226
|
+
this._dynamicDependencyService = _dynamicDependencyService;
|
|
227
|
+
}
|
|
228
|
+
async createChild(delta) {
|
|
229
|
+
const registry = new ServiceRegistry({
|
|
230
|
+
checkDuplicate: true
|
|
231
|
+
});
|
|
232
|
+
this._registerDynamicSharedServices(this._dynamicDependencyService);
|
|
233
|
+
const lazyServiceRegister = (0, lodash_es_exports.curry)(generateRegisterLazyServiceTask)(registry)(
|
|
234
|
+
this._parentContainerService
|
|
235
|
+
);
|
|
236
|
+
await this._registerChildLevelServices(
|
|
237
|
+
{
|
|
238
|
+
registry,
|
|
239
|
+
lazyServiceRegister
|
|
240
|
+
},
|
|
241
|
+
delta
|
|
242
|
+
);
|
|
243
|
+
const childContainerService = this._dynamicDependencyService.createChild(registry.makeCollection());
|
|
244
|
+
return childContainerService;
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
exports.AbstractContainerFactory = __decorateClass([
|
|
248
|
+
__decorateParam(0, IInstantiationService),
|
|
249
|
+
__decorateParam(1, IDynamicDependencyService)
|
|
250
|
+
], exports.AbstractContainerFactory);
|
|
251
|
+
|
|
252
|
+
exports.generateRegisterLazyServiceTask = generateRegisterLazyServiceTask;
|
|
253
|
+
//# sourceMappingURL=index.cjs.map
|
|
254
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/container-factory/generate-register-lazy-service-task.ts","../../src/lodash-es/index.ts","../../src/di/base.ts","../../src/di/descriptor.ts","../../src/di/instantiation-service.interface.ts","../../src/assert/assert.ts","../../src/di/service-ownership-collection.ts","../../src/di/service-collection.ts","../../src/di/service-registry.ts","../../src/services/dynamic-dependency/dynamic-dependency-service.interface.ts","../../src/container-factory/abstract-container-factory.ts"],"names":["lodash_es_star","AbstractContainerFactory"],"mappings":"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","file":"index.cjs","sourcesContent":["// TODO chenchengrong 代码先放在这,感觉是可以挪到 bedrock 提供..\n\nimport type {\n LazyService,\n BrandedService,\n ServiceIdentifier,\n ServicesAccessor,\n ServiceRegistry,\n} from '@/di';\nimport type { IContainerService } from '@/di';\n\n/** 通用函数:允许将一个 lazyService 转化为一个同步的 service 注册到子容器中 */\nexport function generateRegisterLazyServiceTask<TServices extends BrandedService>(\n registry: ServiceRegistry,\n containerService: IContainerService,\n /** 传入目标 services 的标识符 */\n identifier: {\n /** 被 lazy 的服务 */\n lazy: ServiceIdentifier<LazyService<TServices>>;\n /** lazy 服务对应的 instance */\n real: ServiceIdentifier<TServices>;\n },\n): Promise<void> {\n return containerService.invokeFunction((servicesAccessor: ServicesAccessor) => {\n const lazyService = servicesAccessor.get(identifier.lazy);\n\n // eslint-disable-next-line no-async-promise-executor\n return new Promise(async (resolve, reject) => {\n try {\n const instance = await lazyService.getInstance();\n registry.registerInstance(identifier.real, instance);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n","export * from 'lodash-es';\n","// service特征标识\nexport type BrandedService = { _serviceBrand: undefined };\n\n//\n// 服务唯一标识符(编译时生成)\n// 需要DI进行注入的服务必须拥有该标识符\n// 本质上是一个参数装饰器\n//\nexport interface ServiceIdentifier<T> {\n (...args: any[]): void;\n type: T;\n}\n\n// 获取服务的视图接口\nexport interface ServicesAccessor {\n get: <T>(id: ServiceIdentifier<T>) => T;\n}\n\n// 服务唯一标识符存储\nconst serviceIds = new Map<string, ServiceIdentifier<any>>();\n\nexport const DI_TARGET = '$di$target';\nexport const DI_DEPENDENCIES = '$di$dependencies';\n\n// 获取某个服务的依赖\n// 因为服务依赖关系会存放在构造函数的属性上\nexport function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>; index: number }[] {\n return ctor[DI_DEPENDENCIES] || [];\n}\n\n// 更新服务依赖依赖关系\nfunction setServiceDependency(id: ServiceIdentifier<any>, ctor: any, index: number): void {\n if (ctor[DI_TARGET] === ctor) {\n ctor[DI_DEPENDENCIES].push({ id, index });\n } else {\n ctor[DI_DEPENDENCIES] = [{ id, index }];\n ctor[DI_TARGET] = ctor;\n }\n}\n\n//\n// 创建服务唯一标识符\n// 传入服务ID,返回一个参数装饰器\n// 参数装饰器会记录A需要\n// const IFooServiceId = createDecorator<FooService>('FooService');\n//\n// class Bar\n// constructor(@IFooServiceId a: IFooService) // IFooService是接口声明\n//\nexport function createDecorator<T>(serviceId: string): ServiceIdentifier<T> {\n if (serviceIds.has(serviceId)) {\n return serviceIds.get(serviceId)!;\n }\n\n const id = function (target: any, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n setServiceDependency(id, target, index);\n } as any;\n\n id.toString = () => serviceId;\n\n serviceIds.set(serviceId, id);\n return id;\n}\n\n// TODO(niurouwan): 补一下注释和例子\nexport function refineServiceDecorator<T1, T extends T1>(\n serviceIdentifier: ServiceIdentifier<T1>,\n): ServiceIdentifier<T> {\n return serviceIdentifier as ServiceIdentifier<T>;\n}\n","//\n// DI中服务描述符,本质上是构造函数的包装\n//\n// 必须提供服务构造函数\n// 支持静态参数\n// 支持配置是否延迟初始化\n//\nexport class SyncDescriptor<T> {\n readonly ctor: new (...args: any[]) => T;\n readonly staticArguments: any[];\n readonly supportsDelayedInstantiation: boolean;\n\n constructor(\n ctor: new (...args: any[]) => T,\n staticArguments: any[] = [],\n supportsDelayedInstantiation = false,\n ) {\n this.ctor = ctor;\n this.staticArguments = staticArguments;\n this.supportsDelayedInstantiation = supportsDelayedInstantiation;\n }\n}\n\n//\n// 特化描述符\n// 1. 没有静态参数,没有动态参数,只存在注入参数\n// 2. 默认延迟初始化\n//\nexport interface SyncDescriptor0<T> {\n readonly ctor: new () => T;\n}\n","import type { BrandedService, ServicesAccessor } from './base';\nimport { createDecorator } from './base';\nimport type { SyncDescriptor0 } from './descriptor';\nimport type { ServiceCollection } from './service-collection';\n\nexport type GetLeadingNonServiceArgs<TArgs extends any[]> = TArgs extends []\n ? []\n : TArgs extends [...infer TFirst, BrandedService]\n ? GetLeadingNonServiceArgs<TFirst>\n : TArgs;\n\nexport interface IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * Synchronously creates an instance that is denoted by the descriptor\n */\n createInstance: {\n <T>(descriptor: SyncDescriptor0<T>): T;\n <Ctor extends new (...args: any[]) => any, R extends InstanceType<Ctor>>(\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ): R;\n };\n\n /**\n * Calls a function with a service accessor.\n */\n invokeFunction: <R, TS extends any[] = []>(\n fn: (accessor: ServicesAccessor, ...args: TS) => R,\n ...args: TS\n ) => R;\n\n /**\n * Creates a child of this service which inherits all current services\n * and adds/overwrites the given services.\n */\n createChild: (services: ServiceCollection) => IInstantiationService;\n\n /**\n * 生命周期归属该DI上下文的服务进行销毁\n */\n dispose: () => void;\n}\n\nexport const IInstantiationService = createDecorator<IInstantiationService>('instantiation');\n","function abort(reason: string): never {\n throw new Error(`lvAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function lvAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function lvAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function lvAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function lvAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import type { ServiceIdentifier } from './base';\n\nexport enum ServiceOwnership {\n Owned = 1, // 单独持有\n Reference = 2, // 引用子父级类型\n // Shared = 3, // 与兄弟节点共同持有\n}\n\n//\n// 服务的集合\n// key 服务ID\n// value 服务的描述符或者是实例\n//\nexport class ServiceOwnershipCollection {\n private readonly _entries = new Map<ServiceIdentifier<any>, ServiceOwnership>();\n\n constructor(...entries: [ServiceIdentifier<any>, ServiceOwnership][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n get entries() {\n return this._entries;\n }\n\n set(id: ServiceIdentifier<any>, ownership: ServiceOwnership) {\n this._entries.set(id, ownership);\n }\n\n has(id: ServiceIdentifier<any>): boolean {\n return this._entries.has(id);\n }\n\n get(id: ServiceIdentifier<any>): ServiceOwnership | undefined {\n return this._entries.get(id);\n }\n}\n","import type { ServiceIdentifier } from './base';\nimport { SyncDescriptor } from './descriptor';\nimport { ServiceOwnershipCollection } from './service-ownership-collection';\n//\n// 服务的集合\n// key 服务ID\n// value 服务的描述符或者是实例\n//\nexport type IServiceCollection = {\n entries?: [ServiceIdentifier<any>, any][];\n ownership?: ServiceOwnershipCollection;\n};\n\nexport class ServiceCollection {\n private readonly _entries = new Map<ServiceIdentifier<any>, any>();\n private readonly _ownership: ServiceOwnershipCollection | undefined;\n\n constructor(options?: IServiceCollection) {\n for (const [id, service] of options?.entries || []) {\n this.set(id, service);\n }\n if (options?.ownership) {\n this._ownership = options.ownership;\n }\n }\n\n get entries() {\n return this._entries;\n }\n\n get ownerships() {\n return this._ownership?.entries;\n }\n\n set<T>(id: ServiceIdentifier<T>, instanceOrDescriptor: T | SyncDescriptor<T>) {\n this._entries.set(id, instanceOrDescriptor);\n }\n\n has(id: ServiceIdentifier<any>): boolean {\n return this._entries.has(id);\n }\n\n get<T>(id: ServiceIdentifier<T>): T | SyncDescriptor<T> {\n return this._entries.get(id);\n }\n}\n","import { lvAssert } from '../assert';\nimport type { BrandedService, ServiceIdentifier } from './base';\nimport { SyncDescriptor } from './descriptor';\nimport { ServiceCollection } from './service-collection';\nimport { ServiceOwnershipCollection, ServiceOwnership } from './service-ownership-collection';\n\nexport enum InstantiationType {\n Eager = 0,\n Delayed = 1,\n}\n\ninterface IServiceRegistryConfig {\n checkDuplicate?: boolean;\n}\n\nexport class ServiceRegistry {\n protected readonly _registry: [ServiceIdentifier<any>, SyncDescriptor<any> | BrandedService][] = [];\n protected readonly _serviceOwnership: ServiceOwnershipCollection = new ServiceOwnershipCollection();\n // 重复检测的id记录\n private readonly _ids: Set<string> = new Set<string>();\n // 是否进行相同id服务注册的冲突检测\n private readonly _checkDuplicate: boolean;\n\n constructor(config: IServiceRegistryConfig = {}) {\n this._checkDuplicate = config.checkDuplicate ?? false;\n }\n\n get registry() {\n return this._registry;\n }\n\n /**\n * 注册服务,通过传入构造函数或者描述符\n */\n register<T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n ctor: new (...services: Services) => T,\n supportsDelayedInstantiation?: boolean | InstantiationType,\n ): void;\n register<T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n descriptor: SyncDescriptor<any>,\n ): void;\n register<T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n ctorOrDescriptor: { new (...services: Services): T } | SyncDescriptor<any>,\n supportsDelayedInstantiation?: boolean | InstantiationType,\n ) {\n // 无论是构造函数还是描述符,最终加入到registry中的都会转为描述符\n if (!(ctorOrDescriptor instanceof SyncDescriptor)) {\n ctorOrDescriptor = new SyncDescriptor<T>(\n ctorOrDescriptor as new (...args: any[]) => T,\n [],\n Boolean(supportsDelayedInstantiation),\n );\n }\n\n // 如果开启了检测,判断是否有id重复\n if (this._checkDuplicate) {\n lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);\n this._ids.add(id.toString());\n }\n\n this._registry.push([id, ctorOrDescriptor]);\n }\n\n /**\n * 直接注册一个服务的实例\n *\n * 注意:谨慎使用,优先使用register\n * 一般用于特殊场景:需要先于DI之前就构造了某个service\n */\n registerInstance<T extends BrandedService>(\n id: ServiceIdentifier<T>,\n instance: T,\n options?: {\n ownership: ServiceOwnership;\n },\n ) {\n // 如果开启了检测,判断是否有id重复\n if (this._checkDuplicate) {\n lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);\n this._ids.add(id.toString());\n }\n\n this._registry.push([id, instance]);\n this._serviceOwnership.set(id, options?.ownership ?? ServiceOwnership.Owned);\n }\n\n makeCollection(): ServiceCollection {\n const serviceCollection = new ServiceCollection({\n ownership: this._serviceOwnership,\n });\n for (const [id, instanceOrDescriptor] of this.registry) {\n serviceCollection.set(id, instanceOrDescriptor);\n }\n return serviceCollection;\n }\n}\n","import { SyncDescriptor, IInstantiationService, createDecorator } from '@/di';\nimport type { ServiceCollection, BrandedService, ServiceIdentifier } from '@/di';\n\nimport { IContainerService } from '@/di';\n\n/**\n 【动态依赖服务】\n 支持为子容器创建一块动态依赖的构建空间.\n 动态创建出来的服务可以依赖到自身的静态依赖服务, 反之不被允许。\n 子容器可以借助动态层完成一些【多容器间公共依赖】的抽离.可以理解为为了减少静态依赖图在多层设计应用时过于繁琐的一种简化手段.\n -----------------------------\n | InstantiationService |\n -----------------------------\n ↑ lookup service ↑\n -----------------------------\n | DynamicDependencyService |\n -----------------------------\n ↑ lookup service ↑\n -----------------------------\n | ChildContainerService |\n -----------------------------\n */\nexport interface IDynamicDependencyService extends IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * 创建子容器\n */\n createChild: (services: ServiceCollection) => IContainerService;\n\n /**\n * 动态注册 service\n * 重复注册会抛弃后面的服务\n * */\n register: <T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n ctorOrDescriptor: { new (...services: Services): T } | SyncDescriptor<any>,\n ) => void;\n\n /**\n * containerService支持销毁,子containerService都会进行dispose\n */\n dispose: () => void;\n}\n\nexport const IDynamicDependencyService = createDecorator<IDynamicDependencyService>(\n 'dynamic-dependency-service',\n);\n","import { curry } from '../lodash-es';\nimport { IContainerService, ServiceRegistry } from '@/di';\nimport { IDynamicDependencyService } from '@/services/dynamic-dependency';\nimport { generateRegisterLazyServiceTask } from './generate-register-lazy-service-task';\n\ntype Tail<T extends unknown[]> = T extends [unknown, ...infer R] ? R : never;\ntype Skip2<T extends unknown[]> = Tail<Tail<T>>;\n\nexport interface RegisterChildLevelServiceOptions {\n registry: ServiceRegistry;\n lazyServiceRegister: (\n ...params: Skip2<Parameters<typeof generateRegisterLazyServiceTask>>\n ) => ReturnType<typeof generateRegisterLazyServiceTask>;\n}\n\nexport abstract class AbstractContainerFactory<T = void> {\n constructor(\n @IContainerService protected readonly _parentContainerService: IContainerService,\n @IDynamicDependencyService protected readonly _dynamicDependencyService: IDynamicDependencyService,\n ) {}\n\n async createChild(delta?: T): Promise<IContainerService> {\n const registry = new ServiceRegistry({\n checkDuplicate: true,\n });\n\n this._registerDynamicSharedServices(this._dynamicDependencyService);\n const lazyServiceRegister = curry(generateRegisterLazyServiceTask)(registry)(\n this._parentContainerService,\n );\n await this._registerChildLevelServices(\n {\n registry,\n lazyServiceRegister,\n },\n delta,\n );\n const childContainerService = this._dynamicDependencyService.createChild(registry.makeCollection());\n return childContainerService;\n }\n\n /** 注册共享域 services */\n protected abstract _registerDynamicSharedServices(\n dynamicDependencyService: IDynamicDependencyService,\n ): void;\n\n /** 注册本地 services */\n protected abstract _registerChildLevelServices(\n options: RegisterChildLevelServiceOptions,\n delta?: T,\n ): Promise<void>;\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { B as BrandedService, I as IInstantiationService, S as ServiceIdentifier } from '../instantiation-service.interface-bshqO0aS.cjs';
|
|
2
|
+
import { S as ServiceRegistry, L as LazyService } from '../type-BsqwDzaj.cjs';
|
|
3
|
+
import { I as IDynamicDependencyService } from '../dynamic-dependency-service.interface-OUOyz9BD.cjs';
|
|
4
|
+
|
|
5
|
+
/** 通用函数:允许将一个 lazyService 转化为一个同步的 service 注册到子容器中 */
|
|
6
|
+
declare function generateRegisterLazyServiceTask<TServices extends BrandedService>(registry: ServiceRegistry, containerService: IInstantiationService,
|
|
7
|
+
/** 传入目标 services 的标识符 */
|
|
8
|
+
identifier: {
|
|
9
|
+
/** 被 lazy 的服务 */
|
|
10
|
+
lazy: ServiceIdentifier<LazyService<TServices>>;
|
|
11
|
+
/** lazy 服务对应的 instance */
|
|
12
|
+
real: ServiceIdentifier<TServices>;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
|
|
15
|
+
type Tail<T extends unknown[]> = T extends [unknown, ...infer R] ? R : never;
|
|
16
|
+
type Skip2<T extends unknown[]> = Tail<Tail<T>>;
|
|
17
|
+
interface RegisterChildLevelServiceOptions {
|
|
18
|
+
registry: ServiceRegistry;
|
|
19
|
+
lazyServiceRegister: (...params: Skip2<Parameters<typeof generateRegisterLazyServiceTask>>) => ReturnType<typeof generateRegisterLazyServiceTask>;
|
|
20
|
+
}
|
|
21
|
+
declare abstract class AbstractContainerFactory<T = void> {
|
|
22
|
+
protected readonly _parentContainerService: IInstantiationService;
|
|
23
|
+
protected readonly _dynamicDependencyService: IDynamicDependencyService;
|
|
24
|
+
constructor(_parentContainerService: IInstantiationService, _dynamicDependencyService: IDynamicDependencyService);
|
|
25
|
+
createChild(delta?: T): Promise<IInstantiationService>;
|
|
26
|
+
/** 注册共享域 services */
|
|
27
|
+
protected abstract _registerDynamicSharedServices(dynamicDependencyService: IDynamicDependencyService): void;
|
|
28
|
+
/** 注册本地 services */
|
|
29
|
+
protected abstract _registerChildLevelServices(options: RegisterChildLevelServiceOptions, delta?: T): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { AbstractContainerFactory, type RegisterChildLevelServiceOptions, generateRegisterLazyServiceTask };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { B as BrandedService, I as IInstantiationService, S as ServiceIdentifier } from '../instantiation-service.interface-bshqO0aS.js';
|
|
2
|
+
import { S as ServiceRegistry, L as LazyService } from '../type-Bya55PZP.js';
|
|
3
|
+
import { I as IDynamicDependencyService } from '../dynamic-dependency-service.interface-BrwqELkH.js';
|
|
4
|
+
|
|
5
|
+
/** 通用函数:允许将一个 lazyService 转化为一个同步的 service 注册到子容器中 */
|
|
6
|
+
declare function generateRegisterLazyServiceTask<TServices extends BrandedService>(registry: ServiceRegistry, containerService: IInstantiationService,
|
|
7
|
+
/** 传入目标 services 的标识符 */
|
|
8
|
+
identifier: {
|
|
9
|
+
/** 被 lazy 的服务 */
|
|
10
|
+
lazy: ServiceIdentifier<LazyService<TServices>>;
|
|
11
|
+
/** lazy 服务对应的 instance */
|
|
12
|
+
real: ServiceIdentifier<TServices>;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
|
|
15
|
+
type Tail<T extends unknown[]> = T extends [unknown, ...infer R] ? R : never;
|
|
16
|
+
type Skip2<T extends unknown[]> = Tail<Tail<T>>;
|
|
17
|
+
interface RegisterChildLevelServiceOptions {
|
|
18
|
+
registry: ServiceRegistry;
|
|
19
|
+
lazyServiceRegister: (...params: Skip2<Parameters<typeof generateRegisterLazyServiceTask>>) => ReturnType<typeof generateRegisterLazyServiceTask>;
|
|
20
|
+
}
|
|
21
|
+
declare abstract class AbstractContainerFactory<T = void> {
|
|
22
|
+
protected readonly _parentContainerService: IInstantiationService;
|
|
23
|
+
protected readonly _dynamicDependencyService: IDynamicDependencyService;
|
|
24
|
+
constructor(_parentContainerService: IInstantiationService, _dynamicDependencyService: IDynamicDependencyService);
|
|
25
|
+
createChild(delta?: T): Promise<IInstantiationService>;
|
|
26
|
+
/** 注册共享域 services */
|
|
27
|
+
protected abstract _registerDynamicSharedServices(dynamicDependencyService: IDynamicDependencyService): void;
|
|
28
|
+
/** 注册本地 services */
|
|
29
|
+
protected abstract _registerChildLevelServices(options: RegisterChildLevelServiceOptions, delta?: T): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { AbstractContainerFactory, type RegisterChildLevelServiceOptions, generateRegisterLazyServiceTask };
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import * as lodash_es_star from 'lodash-es';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __copyProps = (to, from, except, desc) => {
|
|
8
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
9
|
+
for (let key of __getOwnPropNames(from))
|
|
10
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
11
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
12
|
+
}
|
|
13
|
+
return to;
|
|
14
|
+
};
|
|
15
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget);
|
|
16
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
17
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
18
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
19
|
+
if (decorator = decorators[i])
|
|
20
|
+
result = (decorator(result)) || result;
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
24
|
+
|
|
25
|
+
// src/container-factory/generate-register-lazy-service-task.ts
|
|
26
|
+
function generateRegisterLazyServiceTask(registry, containerService, identifier) {
|
|
27
|
+
return containerService.invokeFunction((servicesAccessor) => {
|
|
28
|
+
const lazyService = servicesAccessor.get(identifier.lazy);
|
|
29
|
+
return new Promise(async (resolve, reject) => {
|
|
30
|
+
try {
|
|
31
|
+
const instance = await lazyService.getInstance();
|
|
32
|
+
registry.registerInstance(identifier.real, instance);
|
|
33
|
+
resolve();
|
|
34
|
+
} catch (err) {
|
|
35
|
+
reject(err);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/lodash-es/index.ts
|
|
42
|
+
var lodash_es_exports = {};
|
|
43
|
+
__reExport(lodash_es_exports, lodash_es_star);
|
|
44
|
+
|
|
45
|
+
// src/di/base.ts
|
|
46
|
+
var serviceIds = /* @__PURE__ */ new Map();
|
|
47
|
+
var DI_TARGET = "$di$target";
|
|
48
|
+
var DI_DEPENDENCIES = "$di$dependencies";
|
|
49
|
+
function setServiceDependency(id, ctor, index) {
|
|
50
|
+
if (ctor[DI_TARGET] === ctor) {
|
|
51
|
+
ctor[DI_DEPENDENCIES].push({ id, index });
|
|
52
|
+
} else {
|
|
53
|
+
ctor[DI_DEPENDENCIES] = [{ id, index }];
|
|
54
|
+
ctor[DI_TARGET] = ctor;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function createDecorator(serviceId) {
|
|
58
|
+
if (serviceIds.has(serviceId)) {
|
|
59
|
+
return serviceIds.get(serviceId);
|
|
60
|
+
}
|
|
61
|
+
const id = function(target, key, index) {
|
|
62
|
+
if (arguments.length !== 3) {
|
|
63
|
+
throw new Error("@IServiceName-decorator can only be used to decorate a parameter");
|
|
64
|
+
}
|
|
65
|
+
setServiceDependency(id, target, index);
|
|
66
|
+
};
|
|
67
|
+
id.toString = () => serviceId;
|
|
68
|
+
serviceIds.set(serviceId, id);
|
|
69
|
+
return id;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/di/descriptor.ts
|
|
73
|
+
var SyncDescriptor = class {
|
|
74
|
+
constructor(ctor, staticArguments = [], supportsDelayedInstantiation = false) {
|
|
75
|
+
this.ctor = ctor;
|
|
76
|
+
this.staticArguments = staticArguments;
|
|
77
|
+
this.supportsDelayedInstantiation = supportsDelayedInstantiation;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/di/instantiation-service.interface.ts
|
|
82
|
+
var IInstantiationService = createDecorator("instantiation");
|
|
83
|
+
|
|
84
|
+
// src/assert/assert.ts
|
|
85
|
+
function abort(reason) {
|
|
86
|
+
throw new Error(`lvAssert(${reason})`);
|
|
87
|
+
}
|
|
88
|
+
function lvAssert(expr, reason) {
|
|
89
|
+
if (!expr) {
|
|
90
|
+
abort(reason ?? "#expr is false");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/di/service-ownership-collection.ts
|
|
95
|
+
var ServiceOwnershipCollection = class {
|
|
96
|
+
constructor(...entries) {
|
|
97
|
+
this._entries = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const [id, service] of entries) {
|
|
99
|
+
this.set(id, service);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
get entries() {
|
|
103
|
+
return this._entries;
|
|
104
|
+
}
|
|
105
|
+
set(id, ownership) {
|
|
106
|
+
this._entries.set(id, ownership);
|
|
107
|
+
}
|
|
108
|
+
has(id) {
|
|
109
|
+
return this._entries.has(id);
|
|
110
|
+
}
|
|
111
|
+
get(id) {
|
|
112
|
+
return this._entries.get(id);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/di/service-collection.ts
|
|
117
|
+
var ServiceCollection = class {
|
|
118
|
+
constructor(options) {
|
|
119
|
+
this._entries = /* @__PURE__ */ new Map();
|
|
120
|
+
for (const [id, service] of options?.entries || []) {
|
|
121
|
+
this.set(id, service);
|
|
122
|
+
}
|
|
123
|
+
if (options?.ownership) {
|
|
124
|
+
this._ownership = options.ownership;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
get entries() {
|
|
128
|
+
return this._entries;
|
|
129
|
+
}
|
|
130
|
+
get ownerships() {
|
|
131
|
+
return this._ownership?.entries;
|
|
132
|
+
}
|
|
133
|
+
set(id, instanceOrDescriptor) {
|
|
134
|
+
this._entries.set(id, instanceOrDescriptor);
|
|
135
|
+
}
|
|
136
|
+
has(id) {
|
|
137
|
+
return this._entries.has(id);
|
|
138
|
+
}
|
|
139
|
+
get(id) {
|
|
140
|
+
return this._entries.get(id);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/di/service-registry.ts
|
|
145
|
+
var ServiceRegistry = class {
|
|
146
|
+
constructor(config = {}) {
|
|
147
|
+
this._registry = [];
|
|
148
|
+
this._serviceOwnership = new ServiceOwnershipCollection();
|
|
149
|
+
// 重复检测的id记录
|
|
150
|
+
this._ids = /* @__PURE__ */ new Set();
|
|
151
|
+
this._checkDuplicate = config.checkDuplicate ?? false;
|
|
152
|
+
}
|
|
153
|
+
get registry() {
|
|
154
|
+
return this._registry;
|
|
155
|
+
}
|
|
156
|
+
register(id, ctorOrDescriptor, supportsDelayedInstantiation) {
|
|
157
|
+
if (!(ctorOrDescriptor instanceof SyncDescriptor)) {
|
|
158
|
+
ctorOrDescriptor = new SyncDescriptor(
|
|
159
|
+
ctorOrDescriptor,
|
|
160
|
+
[],
|
|
161
|
+
Boolean(supportsDelayedInstantiation)
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
if (this._checkDuplicate) {
|
|
165
|
+
lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);
|
|
166
|
+
this._ids.add(id.toString());
|
|
167
|
+
}
|
|
168
|
+
this._registry.push([id, ctorOrDescriptor]);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* 直接注册一个服务的实例
|
|
172
|
+
*
|
|
173
|
+
* 注意:谨慎使用,优先使用register
|
|
174
|
+
* 一般用于特殊场景:需要先于DI之前就构造了某个service
|
|
175
|
+
*/
|
|
176
|
+
registerInstance(id, instance, options) {
|
|
177
|
+
if (this._checkDuplicate) {
|
|
178
|
+
lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);
|
|
179
|
+
this._ids.add(id.toString());
|
|
180
|
+
}
|
|
181
|
+
this._registry.push([id, instance]);
|
|
182
|
+
this._serviceOwnership.set(id, options?.ownership ?? 1 /* Owned */);
|
|
183
|
+
}
|
|
184
|
+
makeCollection() {
|
|
185
|
+
const serviceCollection = new ServiceCollection({
|
|
186
|
+
ownership: this._serviceOwnership
|
|
187
|
+
});
|
|
188
|
+
for (const [id, instanceOrDescriptor] of this.registry) {
|
|
189
|
+
serviceCollection.set(id, instanceOrDescriptor);
|
|
190
|
+
}
|
|
191
|
+
return serviceCollection;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// src/services/dynamic-dependency/dynamic-dependency-service.interface.ts
|
|
196
|
+
var IDynamicDependencyService = createDecorator(
|
|
197
|
+
"dynamic-dependency-service"
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// src/container-factory/abstract-container-factory.ts
|
|
201
|
+
var AbstractContainerFactory = class {
|
|
202
|
+
constructor(_parentContainerService, _dynamicDependencyService) {
|
|
203
|
+
this._parentContainerService = _parentContainerService;
|
|
204
|
+
this._dynamicDependencyService = _dynamicDependencyService;
|
|
205
|
+
}
|
|
206
|
+
async createChild(delta) {
|
|
207
|
+
const registry = new ServiceRegistry({
|
|
208
|
+
checkDuplicate: true
|
|
209
|
+
});
|
|
210
|
+
this._registerDynamicSharedServices(this._dynamicDependencyService);
|
|
211
|
+
const lazyServiceRegister = (0, lodash_es_exports.curry)(generateRegisterLazyServiceTask)(registry)(
|
|
212
|
+
this._parentContainerService
|
|
213
|
+
);
|
|
214
|
+
await this._registerChildLevelServices(
|
|
215
|
+
{
|
|
216
|
+
registry,
|
|
217
|
+
lazyServiceRegister
|
|
218
|
+
},
|
|
219
|
+
delta
|
|
220
|
+
);
|
|
221
|
+
const childContainerService = this._dynamicDependencyService.createChild(registry.makeCollection());
|
|
222
|
+
return childContainerService;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
AbstractContainerFactory = __decorateClass([
|
|
226
|
+
__decorateParam(0, IInstantiationService),
|
|
227
|
+
__decorateParam(1, IDynamicDependencyService)
|
|
228
|
+
], AbstractContainerFactory);
|
|
229
|
+
|
|
230
|
+
export { AbstractContainerFactory, generateRegisterLazyServiceTask };
|
|
231
|
+
//# sourceMappingURL=index.js.map
|
|
232
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/container-factory/generate-register-lazy-service-task.ts","../../src/lodash-es/index.ts","../../src/di/base.ts","../../src/di/descriptor.ts","../../src/di/instantiation-service.interface.ts","../../src/assert/assert.ts","../../src/di/service-ownership-collection.ts","../../src/di/service-collection.ts","../../src/di/service-registry.ts","../../src/services/dynamic-dependency/dynamic-dependency-service.interface.ts","../../src/container-factory/abstract-container-factory.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// TODO chenchengrong 代码先放在这,感觉是可以挪到 bedrock 提供..\n\nimport type {\n LazyService,\n BrandedService,\n ServiceIdentifier,\n ServicesAccessor,\n ServiceRegistry,\n} from '@/di';\nimport type { IContainerService } from '@/di';\n\n/** 通用函数:允许将一个 lazyService 转化为一个同步的 service 注册到子容器中 */\nexport function generateRegisterLazyServiceTask<TServices extends BrandedService>(\n registry: ServiceRegistry,\n containerService: IContainerService,\n /** 传入目标 services 的标识符 */\n identifier: {\n /** 被 lazy 的服务 */\n lazy: ServiceIdentifier<LazyService<TServices>>;\n /** lazy 服务对应的 instance */\n real: ServiceIdentifier<TServices>;\n },\n): Promise<void> {\n return containerService.invokeFunction((servicesAccessor: ServicesAccessor) => {\n const lazyService = servicesAccessor.get(identifier.lazy);\n\n // eslint-disable-next-line no-async-promise-executor\n return new Promise(async (resolve, reject) => {\n try {\n const instance = await lazyService.getInstance();\n registry.registerInstance(identifier.real, instance);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n });\n}\n","export * from 'lodash-es';\n","// service特征标识\nexport type BrandedService = { _serviceBrand: undefined };\n\n//\n// 服务唯一标识符(编译时生成)\n// 需要DI进行注入的服务必须拥有该标识符\n// 本质上是一个参数装饰器\n//\nexport interface ServiceIdentifier<T> {\n (...args: any[]): void;\n type: T;\n}\n\n// 获取服务的视图接口\nexport interface ServicesAccessor {\n get: <T>(id: ServiceIdentifier<T>) => T;\n}\n\n// 服务唯一标识符存储\nconst serviceIds = new Map<string, ServiceIdentifier<any>>();\n\nexport const DI_TARGET = '$di$target';\nexport const DI_DEPENDENCIES = '$di$dependencies';\n\n// 获取某个服务的依赖\n// 因为服务依赖关系会存放在构造函数的属性上\nexport function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>; index: number }[] {\n return ctor[DI_DEPENDENCIES] || [];\n}\n\n// 更新服务依赖依赖关系\nfunction setServiceDependency(id: ServiceIdentifier<any>, ctor: any, index: number): void {\n if (ctor[DI_TARGET] === ctor) {\n ctor[DI_DEPENDENCIES].push({ id, index });\n } else {\n ctor[DI_DEPENDENCIES] = [{ id, index }];\n ctor[DI_TARGET] = ctor;\n }\n}\n\n//\n// 创建服务唯一标识符\n// 传入服务ID,返回一个参数装饰器\n// 参数装饰器会记录A需要\n// const IFooServiceId = createDecorator<FooService>('FooService');\n//\n// class Bar\n// constructor(@IFooServiceId a: IFooService) // IFooService是接口声明\n//\nexport function createDecorator<T>(serviceId: string): ServiceIdentifier<T> {\n if (serviceIds.has(serviceId)) {\n return serviceIds.get(serviceId)!;\n }\n\n const id = function (target: any, key: string, index: number): any {\n if (arguments.length !== 3) {\n throw new Error('@IServiceName-decorator can only be used to decorate a parameter');\n }\n setServiceDependency(id, target, index);\n } as any;\n\n id.toString = () => serviceId;\n\n serviceIds.set(serviceId, id);\n return id;\n}\n\n// TODO(niurouwan): 补一下注释和例子\nexport function refineServiceDecorator<T1, T extends T1>(\n serviceIdentifier: ServiceIdentifier<T1>,\n): ServiceIdentifier<T> {\n return serviceIdentifier as ServiceIdentifier<T>;\n}\n","//\n// DI中服务描述符,本质上是构造函数的包装\n//\n// 必须提供服务构造函数\n// 支持静态参数\n// 支持配置是否延迟初始化\n//\nexport class SyncDescriptor<T> {\n readonly ctor: new (...args: any[]) => T;\n readonly staticArguments: any[];\n readonly supportsDelayedInstantiation: boolean;\n\n constructor(\n ctor: new (...args: any[]) => T,\n staticArguments: any[] = [],\n supportsDelayedInstantiation = false,\n ) {\n this.ctor = ctor;\n this.staticArguments = staticArguments;\n this.supportsDelayedInstantiation = supportsDelayedInstantiation;\n }\n}\n\n//\n// 特化描述符\n// 1. 没有静态参数,没有动态参数,只存在注入参数\n// 2. 默认延迟初始化\n//\nexport interface SyncDescriptor0<T> {\n readonly ctor: new () => T;\n}\n","import type { BrandedService, ServicesAccessor } from './base';\nimport { createDecorator } from './base';\nimport type { SyncDescriptor0 } from './descriptor';\nimport type { ServiceCollection } from './service-collection';\n\nexport type GetLeadingNonServiceArgs<TArgs extends any[]> = TArgs extends []\n ? []\n : TArgs extends [...infer TFirst, BrandedService]\n ? GetLeadingNonServiceArgs<TFirst>\n : TArgs;\n\nexport interface IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * Synchronously creates an instance that is denoted by the descriptor\n */\n createInstance: {\n <T>(descriptor: SyncDescriptor0<T>): T;\n <Ctor extends new (...args: any[]) => any, R extends InstanceType<Ctor>>(\n ctor: Ctor,\n ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>\n ): R;\n };\n\n /**\n * Calls a function with a service accessor.\n */\n invokeFunction: <R, TS extends any[] = []>(\n fn: (accessor: ServicesAccessor, ...args: TS) => R,\n ...args: TS\n ) => R;\n\n /**\n * Creates a child of this service which inherits all current services\n * and adds/overwrites the given services.\n */\n createChild: (services: ServiceCollection) => IInstantiationService;\n\n /**\n * 生命周期归属该DI上下文的服务进行销毁\n */\n dispose: () => void;\n}\n\nexport const IInstantiationService = createDecorator<IInstantiationService>('instantiation');\n","function abort(reason: string): never {\n throw new Error(`lvAssert(${reason})`);\n}\n\n/**\n * 断言表达式为真\n * @param expr \n * @param reason \n */\nexport function lvAssert(expr: unknown, reason?: string): asserts expr {\n if (!expr) {\n abort(reason ?? '#expr is false');\n }\n}\n\n/**\n * 断言deadcode路径\n * @param reason \n */\nexport function lvAssertNotHere(reason?: string): never {\n abort(reason ?? 'unreachable code flow');\n}\n\n/**\n * 断言类型不可达\n * @param member \n * @param message \n */\nexport function lvAssertNever(member: never, message = 'Illegal value:'): never {\n abort(`${message}: ${member}`);\n}\n\n/**\n * 断言变量为null或者undefined\n * @param val \n * @param reason \n */\nexport function lvAssertNotNil<T>(val: T, reason?: string): asserts val is NonNullable<T> {\n if (val === null || val === undefined) {\n abort(reason ?? '#val is nil');\n }\n}\n","import type { ServiceIdentifier } from './base';\n\nexport enum ServiceOwnership {\n Owned = 1, // 单独持有\n Reference = 2, // 引用子父级类型\n // Shared = 3, // 与兄弟节点共同持有\n}\n\n//\n// 服务的集合\n// key 服务ID\n// value 服务的描述符或者是实例\n//\nexport class ServiceOwnershipCollection {\n private readonly _entries = new Map<ServiceIdentifier<any>, ServiceOwnership>();\n\n constructor(...entries: [ServiceIdentifier<any>, ServiceOwnership][]) {\n for (const [id, service] of entries) {\n this.set(id, service);\n }\n }\n\n get entries() {\n return this._entries;\n }\n\n set(id: ServiceIdentifier<any>, ownership: ServiceOwnership) {\n this._entries.set(id, ownership);\n }\n\n has(id: ServiceIdentifier<any>): boolean {\n return this._entries.has(id);\n }\n\n get(id: ServiceIdentifier<any>): ServiceOwnership | undefined {\n return this._entries.get(id);\n }\n}\n","import type { ServiceIdentifier } from './base';\nimport { SyncDescriptor } from './descriptor';\nimport { ServiceOwnershipCollection } from './service-ownership-collection';\n//\n// 服务的集合\n// key 服务ID\n// value 服务的描述符或者是实例\n//\nexport type IServiceCollection = {\n entries?: [ServiceIdentifier<any>, any][];\n ownership?: ServiceOwnershipCollection;\n};\n\nexport class ServiceCollection {\n private readonly _entries = new Map<ServiceIdentifier<any>, any>();\n private readonly _ownership: ServiceOwnershipCollection | undefined;\n\n constructor(options?: IServiceCollection) {\n for (const [id, service] of options?.entries || []) {\n this.set(id, service);\n }\n if (options?.ownership) {\n this._ownership = options.ownership;\n }\n }\n\n get entries() {\n return this._entries;\n }\n\n get ownerships() {\n return this._ownership?.entries;\n }\n\n set<T>(id: ServiceIdentifier<T>, instanceOrDescriptor: T | SyncDescriptor<T>) {\n this._entries.set(id, instanceOrDescriptor);\n }\n\n has(id: ServiceIdentifier<any>): boolean {\n return this._entries.has(id);\n }\n\n get<T>(id: ServiceIdentifier<T>): T | SyncDescriptor<T> {\n return this._entries.get(id);\n }\n}\n","import { lvAssert } from '../assert';\nimport type { BrandedService, ServiceIdentifier } from './base';\nimport { SyncDescriptor } from './descriptor';\nimport { ServiceCollection } from './service-collection';\nimport { ServiceOwnershipCollection, ServiceOwnership } from './service-ownership-collection';\n\nexport enum InstantiationType {\n Eager = 0,\n Delayed = 1,\n}\n\ninterface IServiceRegistryConfig {\n checkDuplicate?: boolean;\n}\n\nexport class ServiceRegistry {\n protected readonly _registry: [ServiceIdentifier<any>, SyncDescriptor<any> | BrandedService][] = [];\n protected readonly _serviceOwnership: ServiceOwnershipCollection = new ServiceOwnershipCollection();\n // 重复检测的id记录\n private readonly _ids: Set<string> = new Set<string>();\n // 是否进行相同id服务注册的冲突检测\n private readonly _checkDuplicate: boolean;\n\n constructor(config: IServiceRegistryConfig = {}) {\n this._checkDuplicate = config.checkDuplicate ?? false;\n }\n\n get registry() {\n return this._registry;\n }\n\n /**\n * 注册服务,通过传入构造函数或者描述符\n */\n register<T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n ctor: new (...services: Services) => T,\n supportsDelayedInstantiation?: boolean | InstantiationType,\n ): void;\n register<T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n descriptor: SyncDescriptor<any>,\n ): void;\n register<T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n ctorOrDescriptor: { new (...services: Services): T } | SyncDescriptor<any>,\n supportsDelayedInstantiation?: boolean | InstantiationType,\n ) {\n // 无论是构造函数还是描述符,最终加入到registry中的都会转为描述符\n if (!(ctorOrDescriptor instanceof SyncDescriptor)) {\n ctorOrDescriptor = new SyncDescriptor<T>(\n ctorOrDescriptor as new (...args: any[]) => T,\n [],\n Boolean(supportsDelayedInstantiation),\n );\n }\n\n // 如果开启了检测,判断是否有id重复\n if (this._checkDuplicate) {\n lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);\n this._ids.add(id.toString());\n }\n\n this._registry.push([id, ctorOrDescriptor]);\n }\n\n /**\n * 直接注册一个服务的实例\n *\n * 注意:谨慎使用,优先使用register\n * 一般用于特殊场景:需要先于DI之前就构造了某个service\n */\n registerInstance<T extends BrandedService>(\n id: ServiceIdentifier<T>,\n instance: T,\n options?: {\n ownership: ServiceOwnership;\n },\n ) {\n // 如果开启了检测,判断是否有id重复\n if (this._checkDuplicate) {\n lvAssert(!this._ids.has(id.toString()), `service: ${id.toString()} duplicate register.`);\n this._ids.add(id.toString());\n }\n\n this._registry.push([id, instance]);\n this._serviceOwnership.set(id, options?.ownership ?? ServiceOwnership.Owned);\n }\n\n makeCollection(): ServiceCollection {\n const serviceCollection = new ServiceCollection({\n ownership: this._serviceOwnership,\n });\n for (const [id, instanceOrDescriptor] of this.registry) {\n serviceCollection.set(id, instanceOrDescriptor);\n }\n return serviceCollection;\n }\n}\n","import { SyncDescriptor, IInstantiationService, createDecorator } from '@/di';\nimport type { ServiceCollection, BrandedService, ServiceIdentifier } from '@/di';\n\nimport { IContainerService } from '@/di';\n\n/**\n 【动态依赖服务】\n 支持为子容器创建一块动态依赖的构建空间.\n 动态创建出来的服务可以依赖到自身的静态依赖服务, 反之不被允许。\n 子容器可以借助动态层完成一些【多容器间公共依赖】的抽离.可以理解为为了减少静态依赖图在多层设计应用时过于繁琐的一种简化手段.\n -----------------------------\n | InstantiationService |\n -----------------------------\n ↑ lookup service ↑\n -----------------------------\n | DynamicDependencyService |\n -----------------------------\n ↑ lookup service ↑\n -----------------------------\n | ChildContainerService |\n -----------------------------\n */\nexport interface IDynamicDependencyService extends IInstantiationService {\n readonly _serviceBrand: undefined;\n\n /**\n * 创建子容器\n */\n createChild: (services: ServiceCollection) => IContainerService;\n\n /**\n * 动态注册 service\n * 重复注册会抛弃后面的服务\n * */\n register: <T, Services extends BrandedService[]>(\n id: ServiceIdentifier<T>,\n ctorOrDescriptor: { new (...services: Services): T } | SyncDescriptor<any>,\n ) => void;\n\n /**\n * containerService支持销毁,子containerService都会进行dispose\n */\n dispose: () => void;\n}\n\nexport const IDynamicDependencyService = createDecorator<IDynamicDependencyService>(\n 'dynamic-dependency-service',\n);\n","import { curry } from '../lodash-es';\nimport { IContainerService, ServiceRegistry } from '@/di';\nimport { IDynamicDependencyService } from '@/services/dynamic-dependency';\nimport { generateRegisterLazyServiceTask } from './generate-register-lazy-service-task';\n\ntype Tail<T extends unknown[]> = T extends [unknown, ...infer R] ? R : never;\ntype Skip2<T extends unknown[]> = Tail<Tail<T>>;\n\nexport interface RegisterChildLevelServiceOptions {\n registry: ServiceRegistry;\n lazyServiceRegister: (\n ...params: Skip2<Parameters<typeof generateRegisterLazyServiceTask>>\n ) => ReturnType<typeof generateRegisterLazyServiceTask>;\n}\n\nexport abstract class AbstractContainerFactory<T = void> {\n constructor(\n @IContainerService protected readonly _parentContainerService: IContainerService,\n @IDynamicDependencyService protected readonly _dynamicDependencyService: IDynamicDependencyService,\n ) {}\n\n async createChild(delta?: T): Promise<IContainerService> {\n const registry = new ServiceRegistry({\n checkDuplicate: true,\n });\n\n this._registerDynamicSharedServices(this._dynamicDependencyService);\n const lazyServiceRegister = curry(generateRegisterLazyServiceTask)(registry)(\n this._parentContainerService,\n );\n await this._registerChildLevelServices(\n {\n registry,\n lazyServiceRegister,\n },\n delta,\n );\n const childContainerService = this._dynamicDependencyService.createChild(registry.makeCollection());\n return childContainerService;\n }\n\n /** 注册共享域 services */\n protected abstract _registerDynamicSharedServices(\n dynamicDependencyService: IDynamicDependencyService,\n ): void;\n\n /** 注册本地 services */\n protected abstract _registerChildLevelServices(\n options: RegisterChildLevelServiceOptions,\n delta?: T,\n ): Promise<void>;\n}\n"]}
|