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

升级到Angular 9时出现MessagingService循环依赖问题如何解决

问题产生原因

Angular 9 版本默认启用了Ivy编译器,相比旧版本的ViewEngine,对依赖注入的循环引用检测严格度大幅提升,之前不会触发报错的隐式循环依赖在新版本会直接抛出异常。你当前遇到的问题本质是MessagingService和注入的ConfirmationService/MessageService存在隐式的互相引用,常见的场景有三类:

  • 你项目内自定义了PrimeNG的全局消息/弹窗组件,该组件内注入了MessagingService,同时该组件在根模块注册时和PrimeNG的ConfirmationService/MessageService形成了依赖绑定
  • 你项目内的其他根级服务(比如HTTP拦截器、路由守卫)同时注入了MessagingService和PrimeNG的消息类服务,形成了间接的循环依赖链
  • 你使用的@ngx-translate/i18n-polyfill的初始化逻辑间接依赖了消息服务相关实例,形成跨服务的循环引用
解决方案

你可以根据你的项目实际情况选择以下任意一种方案修复:

  • 延迟注入有循环风险的服务:不要在构造函数中直接注入MessageService和ConfirmationService,改为通过Injector在调用时按需获取,修改后的代码如下:
import { Injectable, Injector } from '@angular/core';
import { I18n } from '@ngx-translate/i18n-polyfill';
import { isNumber } from 'lodash';
import { ConfirmationService, MessageService } from 'primeng/api';

export enum ConfirmationType {
  Delete,
  Navigate,
  Unsaved,
}

export enum SuccessMessage {
  Cloned,
  Created,
  Deleted,
  Saved,
  Reverted,
}

@Injectable()
export class MessagingService {
  // 通过getter延迟获取服务实例,避开初始化阶段的循环检测
  private get _messageService(): MessageService {
    return this.injector.get(MessageService);
  }

  private get _confirmationService(): ConfirmationService {
    return this.injector.get(ConfirmationService);
  }

  constructor(
    private readonly _i18n: I18n,
    private readonly injector: Injector
  ) { }
  • 调整服务作用域:不要将MessagingService和PrimeNG的消息类服务都注册为根级单例,你可以将MessagingService改为在具体的功能模块中提供,或者拆分MessagingService的功能,把和PrimeNG服务耦合的逻辑抽成单独的子服务,断开循环链
  • 排查并断开循环依赖链:梳理项目的依赖注入关系,找到和MessagingService形成循环引用的服务,把两个服务共同依赖的逻辑抽成无其他依赖的公共工具服务,两边都依赖这个公共工具服务即可消除循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:27:06