/** * 依赖注入装饰器 * 提供类似Java的自动注入功能 */ import { ServiceProvider } from './ServiceProvider' import { ServiceRegistry } from './ServiceRegistry' import 'reflect-metadata'; // 定义构造函数类型 type Constructor = new (...args: any[]) => T // 存储类到服务ID的映射 const classToServiceIdMap = new Map() // 存储服务ID到类的映射 const serviceIdToClassMap = new Map() // 存储需要延迟注册的服务 const pendingServices: Array<{ serviceClass: Constructor serviceId: string dependencies: Array }> = [] /** * 服务装饰器 * 用于标记一个类作为可注入的服务 * @param options 服务配置选项 */ export function Service(options?: { /** 自定义服务ID,如果不提供则使用类名 */ id?: string /** 服务依赖,可以是服务ID字符串或依赖类 */ dependencies?: Array /** 是否为单例模式,默认为true */ singleton?: boolean }): ClassDecorator { return (target: Function) => { // 断言target为Constructor类型 const serviceClass = target as Constructor const serviceId = options?.id || target.name const dependencies = options?.dependencies || [] // 保存映射关系 classToServiceIdMap.set(serviceClass, serviceId) serviceIdToClassMap.set(serviceId, serviceClass) // 将服务添加到待注册列表 pendingServices.push({ serviceClass, serviceId, dependencies }) // 尝试注册服务 tryRegisterPendingServices() } } /** * 注入装饰器 * 用于自动注入服务实例 * @param dependency 依赖的服务类或服务ID */ export function Inject(dependency?: Function | string): PropertyDecorator { return (target: Object, propertyKey: string | symbol) => { // 获取属性的类型(如果使用了TypeScript) const propertyType = Reflect.getMetadata('design:type', target, propertyKey) const descriptor = { get: () => { try { let serviceId: string if (typeof dependency === 'string') { // 直接使用提供的服务ID serviceId = dependency } else if (dependency) { // 使用提供的类获取服务ID serviceId = getServiceIdForClass(dependency) } else if (propertyType) { // 使用属性类型获取服务ID serviceId = getServiceIdForClass(propertyType) } else { throw new Error(`无法确定属性 ${String(propertyKey)} 的注入类型`) } return ServiceProvider.getService(serviceId) } catch (error) { console.error(`注入服务失败: ${String(propertyKey)}`, error) throw error } } } Object.defineProperty(target, propertyKey, descriptor) } } /** * 获取类对应的服务ID * @param cls 服务类 */ function getServiceIdForClass(cls: Function): string { const serviceId = classToServiceIdMap.get(cls) if (!serviceId) { throw new Error(`类 ${cls.name} 未注册为服务`) } return serviceId } /** * 尝试注册所有待注册的服务 */ function tryRegisterPendingServices(): void { if (pendingServices.length === 0) { return } try { const registry = ServiceRegistry.getInstance() const container = registry.getContainer() // 处理所有待注册的服务 for (const pendingService of pendingServices.slice()) { // 解析依赖的服务ID const resolvedDependencies: string[] = [] for (const dep of pendingService.dependencies) { if (typeof dep === 'string') { resolvedDependencies.push(dep) } else if (typeof dep === 'function') { const depServiceId = classToServiceIdMap.get(dep) if (depServiceId) { resolvedDependencies.push(depServiceId) } else { // 依赖尚未注册,跳过当前服务 continue } } } // 检查所有依赖是否都已注册 const allDependenciesRegistered = resolvedDependencies.every(depId => container.has(depId) ) if (allDependenciesRegistered) { // 注册服务 container.register( pendingService.serviceId, (container) => { // 创建服务实例 const ServiceClass = pendingService.serviceClass // 使用依赖注入创建实例 const instance = new ServiceClass() return instance }, resolvedDependencies ) // 从待注册列表中移除 const index = pendingServices.indexOf(pendingService) if (index > -1) { pendingServices.splice(index, 1) } } } } catch (error) { // 服务注册表可能尚未初始化,稍后再试 console.debug('服务注册暂时失败,将在初始化时重试:') } } /** * 初始化所有待注册的服务 * 在ServiceProvider初始化后调用 */ export function initializePendingServices(): void { // 重试注册所有剩余的服务 while (pendingServices.length > 0) { const beforeCount = pendingServices.length tryRegisterPendingServices() // 如果没有服务被注册,可能存在循环依赖,跳出循环 if (beforeCount === pendingServices.length) { console.warn('以下服务无法注册,可能存在循环依赖:', pendingServices.map(s => s.serviceId).join(', ')) break } } } /** * 获取所有已注册的服务信息 */ export function getRegisteredServices(): Array<{ serviceId: string serviceClass: Function }> { return Array.from(classToServiceIdMap.entries()).map(([cls, id]) => ({ serviceId: id, serviceClass: cls })) }