Angular不同模块中为何获取到同一Service实例?
Angular依赖注入问题:模块配置同个Service却拿到同一实例
问题根源
你遇到的情况是Angular注入器机制导致的:
- 同步模块的providers共享根注入器:从Angular 6开始,所有被同步导入的模块(比如你的
FirstModule被AppModule直接import),它们providers里的服务都会注册到根注入器。不管你在多少个同步模块里配置同一个Service,最终根注入器只会生成一个单例,所有组件都拿这个实例。 - 根模块providers优先级最高:你同时在
AppModule(根模块)的providers里声明了FirstService,根注入器会优先创建并使用这个实例,FirstModule里的配置相当于被覆盖了。
解决办法
如果要让不同模块/组件拿到独立的Service实例,有几个可行方案:
1. 改用懒加载模块
把FirstModule改成懒加载,它会生成自己独立的模块注入器,此时FirstModule的providers里的Service会成为该模块专属的单例,和根注入器完全隔离:
- 修改路由配置,设置懒加载:
// app-routing.module.ts const routes: Routes = [ { path: 'first', loadChildren: () => import('./first/first.module').then(m => m.FirstModule) } ];
- 删掉
AppModule里对FirstModule的直接import,同时移除AppModule的providers中的FirstService。
2. 组件级别配置providers
如果只需要组件拥有独立实例,直接在组件的@Component里加providers:
@Component({ selector: 'app-first', templateUrl: './first.component.html', styleUrls: ['./first.component.scss'], providers: [FirstService] // 每个组件实例都会对应一个新的Service实例 }) export class FirstComponent implements OnInit{ // ... }
3. 用@Injectable的providedIn指定注入范围
给FirstService加上providedIn,明确让它属于FirstModule:
@Injectable({ providedIn: FirstModule // 该Service仅在FirstModule及其子组件中可用,且是模块级单例 }) export class FirstService { public randomNumberAsStr: string; constructor() { this.randomNumberAsStr = (Math.random() * 100).toFixed(); } }
同时删掉AppModule和FirstModule的providers里的FirstService配置。
验证效果
按上面任意一种方式修改后,FirstComponent和SecondComponent打印的随机数就会不一样,实现你想要的独立实例效果。
内容的提问来源于stack exchange,提问作者Iceneo
相关产品推荐
相关产品推荐

