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 <clio-agent@sisyphuslabs.ai>
This commit is contained in:
yuding
2026-02-28 10:08:27 +08:00
parent fdc6f884aa
commit 963e0d6cad
3 changed files with 33 additions and 23 deletions

View File

@@ -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子类必须实现 */

View File

@@ -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;
}
/**

View File

@@ -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;
}
/**