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

Angular为Injectable服务提供InjectionToken报NullInjectorError如何解决

问题原因

报错来自两个配置错误,本质是Angular依赖注入的层级和注册规则不匹配:

  • 服务注册层级错位
    你给SharedService加了@Injectable({providedIn: 'root'})装饰器,这会把服务直接注册到全局根注入器,应用启动时根注入器就会尝试解析它的所有依赖。但API_REQUESTS这个注入令牌的提供者,是在业务模块里通过ApiModule.forRoot([])注册的:如果这个业务模块是懒加载模块,它的提供者会被挂在懒加载模块自己的子注入器上,根注入器没有权限访问子注入器的内容,自然找不到对应的令牌。
    同时你在业务模块的providers数组里又重复声明了一次SharedService,这会额外生成一个服务实例,本身就违背了共享服务单例的设计预期。
  • forRoot()方法使用位置错误
    Angular 中forRoot()是约定俗成的全局配置方法,只能在根模块(AppModule)调用一次,用来注册全局单例的服务、配置令牌。你在业务模块调用forRoot(),会直接导致提供者注册的层级混乱,在懒加载场景下还会出现服务重复实例化的问题。
修复方案

按以下步骤调整即可解决问题:

  1. 移除SharedService上的providedIn: 'root'配置,避免服务提前注册到不对的注入器层级:
    @Injectable()
    export class SharedService{
        constructor(
            private store: Store,
            @Inject(API_REQUESTS) private apiRequests: ApiRequestInterface[]
        ) {
            debugger;
        }
    }
    
  2. 把SharedService加入ApiModule.forRoot()返回的提供者列表,保证服务和它依赖的API_REQUESTS令牌注册在同一个注入器,同时给入参加默认空数组避免传空时出现undefined:
    static forRoot(apiRequests: ApiRequestInterface[] = []): ModuleWithProviders<ApiModule> {
        return {
            ngModule: ApiModule,
            providers: [
                SharedService,
                {provide: API_REQUESTS, useValue: apiRequests}
            ]
        };
    }
    
  3. 调整模块导入规则:
    • 只在根模块AppModule中调用ApiModule.forRoot(你的实际API配置数组),所有其他业务模块(包括懒加载模块)如果需要用到ApiModule的能力,直接导入ApiModule本身即可,绝对不要在业务模块调用forRoot()
    • 删掉所有业务模块providers数组里的SharedService声明,避免重复生成服务实例
  4. (可选优化)补全ApiModule构造函数里的重复导入检测逻辑,避免后续误用:
    constructor(@Optional() @SkipSelf() parentModule: ApiModule ) {
        if (parentModule) {
            throw new Error('ApiModule仅可在根模块通过forRoot()导入,业务模块请直接导入ApiModule本身');
        }
    }
    

调整完成后,服务和依赖的令牌都在根注入器注册,层级匹配,就不会再出现找不到注入器的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:45:42