/**
* @file 服务容器实现
* @description 依赖注入容器的核心实现
* @author JunBin.Yang
*/
import { Unknown, SymbolToString } from "@core/common";
import { Container } from './Container';
import { ServiceKey, ServiceFactory, ServiceDescriptor, ServiceOptions } from './ServiceProvider';
/**
* 服务容器实现类
* 提供依赖注入的核心功能
*/
export class ServiceContainer implements Container {
/**
* 服务注册表
*/
private services: Map<ServiceKey, ServiceDescriptor<Unknown>> = new Map();
/**
* 父容器引用(用于子容器)
*/
private parent?: ServiceContainer;
/**
* 构造函数
* @param parent 父容器(可选)
*/
constructor(parent?: ServiceContainer) {
this.parent = parent;
}
/**
* 注册服务
* @template T 服务类型
* @param key 服务标识符
* @param factory 服务工厂函数
* @param options 注册选项
*/
register<T>(key: ServiceKey, factory: ServiceFactory<T>, options?: ServiceOptions): void {
const singleton = options?.singleton !== false; // 默认为单例
const descriptor: ServiceDescriptor<T> = {
factory,
singleton,
instance: undefined
};
this.services.set(key, descriptor as ServiceDescriptor<Unknown>);
}
/**
* 解析服务实例
* @template T 服务类型
* @param key 服务标识符
* @param default_factory 默认服务工厂函数
* @returns 服务实例
* @throws 服务未注册时抛出异常
*/
resolve<T>(key: ServiceKey, default_factory?: ServiceFactory<T>): T {
const instance = this.tryResolve<T>(key);
if (instance !== undefined) {
return instance;
}
if (default_factory === undefined) {
const keyStr = typeof key === 'symbol' ? SymbolToString(key) : key;
throw new Error(`[ServiceContainer] Service not registered: ${keyStr}`);
}
this.register(key, default_factory);
return this.resolve<T>(key);
}
/**
* 尝试解析服务实例
* @template T 服务类型
* @param key 服务标识符
* @returns 服务实例,未注册时返回 undefined
*/
tryResolve<T>(key: ServiceKey): T | undefined {
// 先从当前容器查找
const descriptor = this.services.get(key) as ServiceDescriptor<T> | undefined;
if (descriptor) {
return this.getInstance<T>(descriptor);
}
// 从父容器查找
if (this.parent) {
return this.parent.tryResolve<T>(key);
}
return undefined;
}
/**
* 获取服务实例
* @template T 服务类型
* @param descriptor 服务描述符
* @returns 服务实例
*/
private getInstance<T>(descriptor: ServiceDescriptor<T>): T {
if (descriptor.singleton) {
// 单例模式:缓存实例
if (descriptor.instance === undefined) {
descriptor.instance = descriptor.factory();
}
return descriptor.instance;
}
// 非单例模式:每次创建新实例
return descriptor.factory();
}
/**
* 检查服务是否已注册
* @param key 服务标识符
* @returns 是否已注册
*/
has(key: ServiceKey): boolean {
if (this.services.has(key)) {
return true;
}
if (this.parent) {
return this.parent.has(key);
}
return false;
}
/**
* 注销服务
* @param key 服务标识符
* @returns 是否注销成功
*/
unregister(key: ServiceKey): boolean {
return this.services.delete(key);
}
/**
* 清空所有已注册的服务
*/
clear(): void {
this.services.clear();
}
/**
* 创建子容器
* @returns 子容器实例
*/
createChild(): Container {
return new ServiceContainer(this);
}
/**
* 获取已注册的服务数量
* @returns 服务数量
*/
get size(): number {
return this.services.size;
}
/**
* 获取所有已注册的服务键
* @returns 服务键数组
*/
getKeys(): ServiceKey[] {
return Array.from(this.services.keys());
}
}