如何控制Angular通过注入令牌创建新的工厂对象实例?
解决方案
情况1:每次注入都获取新的MyClass实例
你当前的TOKEN因为设置了providedIn: 'root',属于根注入器的单例,整个应用只会创建一次实例,所有注入点共享同一个对象。要让每次注入都得到新实例,可按以下步骤修改:
步骤1:修改Token定义,移除全局提供配置
export const TOKEN = new InjectionToken<MyClass>('MY CLASS');
步骤2:在组件/模块的providers中局部注册Token
- 若希望每个组件实例拥有独立的
MyClass实例,在组件元数据中配置providers:
@Component({ selector: 'app-target-component', templateUrl: './target-component.component.html', providers: [ { provide: TOKEN, useFactory: () => new MyClass() } ] }) export class TargetComponent { constructor(@Inject(TOKEN) private myClassInstance: MyClass) { // 每个TargetComponent实例的myClassInstance都是全新的 } }
- 若希望某个模块下的所有组件共享同一个新实例(与根注入器实例隔离),则在模块的
providers中注册即可。
情况2:运行时主动丢弃旧实例,后续注入使用新实例
如果需要在应用运行过程中主动替换实例,让之后的注入点获取新对象,可通过实例管理服务实现:
1. 创建实例管理服务
@Injectable({ providedIn: 'root' }) export class MyClassInstanceManager { private _currentInstance: MyClass; constructor() { this._currentInstance = new MyClass(); } get currentInstance(): MyClass { return this._currentInstance; } createNewInstance(): MyClass { this._currentInstance = new MyClass(); return this._currentInstance; } }
2. 修改Token的factory逻辑
让Token的实例指向管理服务中的当前实例:
export const TOKEN = new InjectionToken<MyClass>('MY CLASS', { providedIn: 'root', factory: (injector) => injector.get(MyClassInstanceManager).currentInstance });
3. 主动触发实例替换
在需要替换实例的地方调用管理服务的方法:
export class SomeService { constructor(private manager: MyClassInstanceManager) {} replaceMyClassInstance() { this.manager.createNewInstance(); // 之后所有注入TOKEN的地方都会获取到新实例 } }
注意:已注入的旧实例不会自动更新,若组件已持有旧实例,需主动从管理服务中重新获取当前实例才能使用新对象。
内容的提问来源于stack exchange,提问作者patrick
相关产品推荐
相关产品推荐

