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
相关产品推荐
相关产品推荐

