136 lines
3.8 KiB
TypeScript
136 lines
3.8 KiB
TypeScript
|
|
/**
|
|||
|
|
* 插件服务注册表
|
|||
|
|
* Plugin Service Registry
|
|||
|
|
*
|
|||
|
|
* 基于 ServiceToken 的类型安全服务注册表。
|
|||
|
|
* Type-safe service registry based on ServiceToken.
|
|||
|
|
*
|
|||
|
|
* 设计原则 | Design principles:
|
|||
|
|
* 1. 类型安全 - 使用 ServiceToken 携带类型信息
|
|||
|
|
* 2. 显式依赖 - 通过导入 token 明确表达依赖关系
|
|||
|
|
* 3. 可选依赖 - get 返回 undefined,require 抛异常
|
|||
|
|
* 4. 单一职责 - 只负责服务注册和查询,不涉及生命周期管理
|
|||
|
|
* 5. 谁定义接口,谁导出 Token - 各模块定义自己的接口和 Token
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// 服务令牌 | Service Token
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 服务令牌接口
|
|||
|
|
* Service token interface
|
|||
|
|
*
|
|||
|
|
* 用于类型安全的服务注册和获取。
|
|||
|
|
* For type-safe service registration and retrieval.
|
|||
|
|
*
|
|||
|
|
* 注意:__phantom 是必需属性,确保 TypeScript 在跨包类型解析时保留泛型类型信息。
|
|||
|
|
* Note: __phantom is a required property to ensure TypeScript preserves generic
|
|||
|
|
* type information across packages.
|
|||
|
|
*/
|
|||
|
|
export interface ServiceToken<T> {
|
|||
|
|
readonly id: symbol;
|
|||
|
|
readonly name: string;
|
|||
|
|
/**
|
|||
|
|
* Phantom type 标记(强制类型推断)
|
|||
|
|
* Phantom type marker (enforces type inference)
|
|||
|
|
*/
|
|||
|
|
readonly __phantom: T;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建服务令牌
|
|||
|
|
* Create a service token
|
|||
|
|
*
|
|||
|
|
* @param name 令牌名称 | Token name
|
|||
|
|
* @returns 服务令牌 | Service token
|
|||
|
|
*/
|
|||
|
|
export function createServiceToken<T>(name: string): ServiceToken<T> {
|
|||
|
|
// __phantom 仅用于类型推断,运行时不需要实际值
|
|||
|
|
// __phantom is only for type inference, no actual value needed at runtime
|
|||
|
|
return {
|
|||
|
|
id: Symbol(name),
|
|||
|
|
name
|
|||
|
|
} as ServiceToken<T>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// 插件服务注册表 | Plugin Service Registry
|
|||
|
|
// ============================================================================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 插件服务注册表
|
|||
|
|
* Plugin service registry
|
|||
|
|
*
|
|||
|
|
* 用于跨插件共享服务的类型安全注册表。
|
|||
|
|
* Type-safe registry for sharing services between plugins.
|
|||
|
|
*/
|
|||
|
|
export class PluginServiceRegistry {
|
|||
|
|
private _services = new Map<symbol, unknown>();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 注册服务
|
|||
|
|
* Register a service
|
|||
|
|
*/
|
|||
|
|
register<T>(token: ServiceToken<T>, service: T): void {
|
|||
|
|
this._services.set(token.id, service);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取服务(可选)
|
|||
|
|
* Get a service (optional)
|
|||
|
|
*/
|
|||
|
|
get<T>(token: ServiceToken<T>): T | undefined {
|
|||
|
|
return this._services.get(token.id) as T | undefined;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取服务(必需)
|
|||
|
|
* Get a service (required)
|
|||
|
|
*
|
|||
|
|
* @throws 如果服务未注册 | If service is not registered
|
|||
|
|
*/
|
|||
|
|
require<T>(token: ServiceToken<T>): T {
|
|||
|
|
const service = this._services.get(token.id);
|
|||
|
|
if (service === undefined) {
|
|||
|
|
throw new Error(`Service not found: ${token.name}`);
|
|||
|
|
}
|
|||
|
|
return service as T;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查服务是否已注册
|
|||
|
|
* Check if a service is registered
|
|||
|
|
*/
|
|||
|
|
has<T>(token: ServiceToken<T>): boolean {
|
|||
|
|
return this._services.has(token.id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 注销服务
|
|||
|
|
* Unregister a service
|
|||
|
|
*/
|
|||
|
|
unregister<T>(token: ServiceToken<T>): boolean {
|
|||
|
|
return this._services.delete(token.id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清空所有服务
|
|||
|
|
* Clear all services
|
|||
|
|
*/
|
|||
|
|
clear(): void {
|
|||
|
|
this._services.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 释放资源
|
|||
|
|
* Dispose resources
|
|||
|
|
*
|
|||
|
|
* 实现 IService 接口,在服务容器清理时调用。
|
|||
|
|
* Implements IService interface, called when service container is cleaned up.
|
|||
|
|
*/
|
|||
|
|
dispose(): void {
|
|||
|
|
this.clear();
|
|||
|
|
}
|
|||
|
|
}
|