You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular如何实现调用时获取瞬态Handler服务实例?

解决方案

要实现每次调用callHandler时获取IMyHandler的新实例,你需要调整依赖注入的方式,避免直接使用全局单例,改用动态创建实例的方案:

1. 调整Handler类的注入配置

移除所有IMyHandler实现类的providedIn: 'root'配置,防止它们被注册为全局单例:

export interface IMyHandler {
  run(): void;
}

@Injectable() // 去掉providedIn: 'root'
export class MyHandler1 implements IMyHandler {    
  private somethingElse = inject(SomeOtherClass);

  public run(): void {      
    // 业务逻辑实现
  }
}

@Injectable() // 去掉providedIn: 'root'
export class MyHandler2 implements IMyHandler {    
  private somethingElse = inject(SomeOtherClass);

  public run(): void {      
    // 业务逻辑实现
  }
}

2. 修改LookupService实现

将customHandlersMap改为存储Handler类的类型,注入Injector来动态创建新实例:

import { Injectable, Injector, Type } from '@angular/core';
import { IMyHandler, MyHandler1, MyHandler2 } from './path-to-handlers';

@Injectable({
  providedIn: 'root'
})
export class LookupService {

  private customHandlersMap: Map<string, Type<IMyHandler>> = new Map();
  private readonly injector: Injector;

  constructor(injector: Injector) {
    this.injector = injector;
    // 注册Handler类类型
    this.customHandlersMap.set('M1', MyHandler1);
    this.customHandlersMap.set('M2', MyHandler2);
  }

  public getHandlerByName(key: string): IMyHandler | undefined {
    const HandlerClass = this.customHandlersMap.get(key);
    if (!HandlerClass) return undefined;

    // 创建子注入器,每次生成新的Handler实例
    const childInjector = Injector.create({
      parent: this.injector,
      providers: [{ provide: HandlerClass }]
    });

    return childInjector.get(HandlerClass);
  }
}

3. 组件调用逻辑保持不变

MyComponent的代码无需修改,调用callHandler时会自动获取新的Handler实例:

@Component({
  templateUrl: './some.component.html',
  styleUrls: ['./some.component.scss']
})
export class MyComponent {
 constructor(private lookupService: LookupService) {
 }
 
 public callHandler(key: string) {
   const handler = this.lookupService.getHandlerByName(key);
   if (handler) handler.run();
 }
}

原理说明

  • 子注入器每次创建时,会根据传入的providers生成对应类的新实例,不会复用全局注入器的单例
  • Handler类中的依赖(如SomeOtherClass)会从父注入器(全局)获取,保持原有单例特性
  • 仅需在customHandlersMap中注册Handler类,无需在组件/模块的providers中逐个声明所有Handler

内容的提问来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:37:32