Angular懒加载模块NullInjectorError求助:服务注入失败
你遇到的NullInjectorError核心原因有两点:
服务注入器层级冲突
你的PublicationsRequestService通过@Injectable({ providedIn: 'root' })已经注册到根注入器,这意味着该服务的实例是全局唯一的。但你在懒加载模块的providers数组中又重复添加了PublicationsRequestService,这会导致懒加载模块的注入器创建一个独立的服务实例,和根注入器的实例相互隔离。路由解析器的注入器限制
Angular的路由解析器(Resolver)、守卫(Guard)等路由相关服务,默认由根注入器创建和管理,它们无法访问懒加载模块注入器中的提供者。当你在解析器中注入PUBLICATIONS_REQUEST_SERVICE_TOKEN时,根注入器找不到对应的提供者,就会抛出错误。而组件属于懒加载模块的注入器范围,仅在组件中注入令牌可能不会报错,但解析器会触发问题。
根据你的需求(不在根模块配置提供者,同时支持类和令牌注入),可以按以下方式调整:
方案1:清理模块冗余配置 + 绑定解析器到模块注入器
首先删除懒加载模块publications-request.module.ts中providers数组里的PublicationsRequestService,避免创建重复实例:
providers: [ { provide: PUBLICATIONS_REQUEST_SERVICE_TOKEN, useExisting: PublicationsRequestService } // 移除 PublicationsRequestService 这一行 ]
如果需要在解析器中使用令牌,需将解析器也注册到懒加载模块的providers数组中,让解析器使用模块级注入器:
// publications-request.module.ts providers: [ { provide: PUBLICATIONS_REQUEST_SERVICE_TOKEN, useExisting: PublicationsRequestService }, // 添加你的解析器到这里 PublicationsRequestResolver ]
同时路由配置中不要通过providers字段注册解析器,依赖模块的提供者即可。
方案2:服务层直接绑定令牌(无需模块配置)
如果不想在任何模块中配置提供者,可以直接在服务文件中完成令牌的根注入器注册,既保持服务全局唯一性,又支持令牌注入:
// 令牌定义 export const PUBLICATIONS_REQUEST_SERVICE_TOKEN = new InjectionToken<IPublicationsRequestService>('IPublicationsRequestService'); // 服务类 @Injectable({ providedIn: 'root' }) export class PublicationsRequestService extends BaseRepositoryService<PublicationsRequest> implements IPublicationsRequestService { } // 令牌提供者,自动注册到根注入器 @Injectable({ providedIn: 'root', provide: PUBLICATIONS_REQUEST_SERVICE_TOKEN, useExisting: PublicationsRequestService }) export class PublicationsRequestTokenProvider {}
这样无论在组件还是解析器中,都能通过@Inject(PUBLICATIONS_REQUEST_SERVICE_TOKEN)正常注入,无需在任何模块的providers数组中添加配置。
内容的提问来源于stack exchange,提问作者Sam

