From 963e0d6cadef3e1fe89b242ebc1896c6f0ce7655 Mon Sep 17 00:00:00 2001 From: yuding <1023798085@qq.com> Date: Sat, 28 Feb 2026 10:08:27 +0800 Subject: [PATCH] refactor(core): remove ManagerRegistry singleton, use instance-based DI Replace static getInstance() pattern with public constructor to enable multiple independent BimEngine instances on the same page. BaseManager and BaseDialogManager now accept registry via constructor parameter. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/core/base-dialog-manager.ts | 5 ++++ src/core/base-manager.ts | 6 ++--- src/core/manager-registry.ts | 45 ++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/core/base-dialog-manager.ts b/src/core/base-dialog-manager.ts index 865b823..db212e0 100644 --- a/src/core/base-dialog-manager.ts +++ b/src/core/base-dialog-manager.ts @@ -3,6 +3,7 @@ * 提供对话框的通用生命周期管理 */ import { BaseManager } from './base-manager'; +import { ManagerRegistry } from './manager-registry'; import { BimDialog } from '../components/dialog'; /** 对话框配置选项 */ @@ -23,6 +24,10 @@ export abstract class BaseDialogManager extends BaseManager { /** 对话框是否可见 */ protected isVisible: boolean = false; + constructor(registry: ManagerRegistry) { + super(registry); + } + /** 对话框唯一标识(子类必须实现) */ protected abstract get dialogId(): string; /** 对话框标题,支持国际化 key(子类必须实现) */ diff --git a/src/core/base-manager.ts b/src/core/base-manager.ts index 1dc3b0d..2240806 100644 --- a/src/core/base-manager.ts +++ b/src/core/base-manager.ts @@ -7,7 +7,7 @@ import type { EngineEvents } from '../types/events'; /** * Manager 抽象基类 - * - 自动获取 Registry 实例 + * - 通过构造函数接收 Registry 实例 * - 自动管理事件订阅的清理 */ export abstract class BaseManager { @@ -16,8 +16,8 @@ export abstract class BaseManager { /** 事件订阅列表,用于自动清理 */ private subscriptions: Array<() => void> = []; - constructor() { - this.registry = ManagerRegistry.getInstance(); + constructor(registry: ManagerRegistry) { + this.registry = registry; } /** diff --git a/src/core/manager-registry.ts b/src/core/manager-registry.ts index cbae349..01a240f 100644 --- a/src/core/manager-registry.ts +++ b/src/core/manager-registry.ts @@ -1,6 +1,6 @@ /** * Manager 注册表 - * 全局单例,提供所有 Manager 的集中访问点 + * 每个 BimEngine 实例持有独立的 Registry,实现多实例隔离 */ import { EventEmitter } from './event-emitter'; import type { EngineEvents } from '../types/events'; @@ -24,12 +24,10 @@ import type { ComponentDetailManager } from '../managers/component-detail-manage import type { AiChatManager } from '../managers/ai-chat-manager'; /** - * Manager 注册表 - 单例模式 - * 提供所有 Manager 的全局访问点,替代 engine 层层传递 + * Manager 注册表 - 实例模式 + * 每个 BimEngine 创建独立的 Registry 实例,替代旧的全局单例 */ export class ManagerRegistry { - /** 单例实例 */ - private static instance: ManagerRegistry | null = null; /** 事件发射器 */ private eventEmitter: EventEmitter = new EventEmitter(); @@ -72,22 +70,29 @@ export class ManagerRegistry { /** AI 聊天管理器 */ public aiChat: AiChatManager | null = null; - private constructor() {} + constructor() {} - /** 获取单例实例 */ - public static getInstance(): ManagerRegistry { - if (!ManagerRegistry.instance) { - ManagerRegistry.instance = new ManagerRegistry(); - } - return ManagerRegistry.instance; - } - - /** 重置单例(用于测试或重新初始化) */ - public static reset(): void { - if (ManagerRegistry.instance) { - ManagerRegistry.instance.eventEmitter.clear(); - ManagerRegistry.instance = null; - } + /** 重置(清理事件和引用) */ + public reset(): void { + this.eventEmitter.clear(); + this.container = null; + this.wrapper = null; + this.toolbar = null; + this.dialog = null; + this.engine3d = null; + this.buttonGroup = null; + this.rightKey = null; + this.constructTree = null; + this.measure = null; + this.walkControl = null; + this.sectionPlane = null; + this.sectionAxis = null; + this.sectionBox = null; + this.walkPath = null; + this.walkPlanView = null; + this.engineInfo = null; + this.componentDetail = null; + this.aiChat = null; } /**