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

Angular 14:为何非根模块共享同一单例服务实例?

为什么你的Angular服务始终保持单例?

核心根源:providedIn: 'root'的全局注入优先级

如果你的CoursesService使用了@Injectable({ providedIn: 'root' }),无论你在哪个模块的providers数组中声明它,Angular根注入器都会优先提供这个服务的单例实例。框架会自动忽略模块级别providers中的重复声明,确保根注入器的实例在整个应用中共享。

哪怕你把服务添加到多个模块的providers,或是改用懒加载模块,只要providedIn: 'root'存在,所有组件和模块都会从根注入器获取同一个实例。

关于你的模块导入场景

你提到list-courses.module仅被orders.module导入(未直接导入AppModule),但create-courses.module仍能拿到单例:

  • 只要服务标记了providedIn: 'root',它就属于根注入器,和模块的导入层级毫无关系。create-courses.module中的组件会直接从根注入器拉取服务实例,不管它所在模块和list-courses.module是否有关联。
  • 只有当你完全移除providedIn: 'root',且仅在某个非根模块的providers中声明服务,同时该模块是懒加载状态时,才会创建局部注入器的独立实例。如果是预加载(eager loaded)模块——哪怕不是直接导入AppModule,而是被其他预加载模块导入——它的providers中的服务依然会被提升到根注入器,最终还是单例。

懒加载模块的特殊情况

只有当懒加载模块中声明了该服务(且未使用providedIn: 'root'),才会为该模块的注入器创建独立实例。如果服务用了providedIn: 'root',懒加载模块里的组件依然会使用根注入器的单例,因为Angular会优先复用根注入器的实例,不会为懒加载模块重新创建。

快速验证方法

打开你的courses.service.ts:

  • 如果存在@Injectable({ providedIn: 'root' }),这就是单例的直接原因。
  • 若要实现非单例,需要移除providedIn: 'root',并且仅在目标懒加载模块的providers数组中声明该服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 00:45:07