Angular使用useFactory为服务传参时遇NG2003错误求助
Angular 13中使用useFactory给服务传参时NG2003错误的正确解决方法
问题原因
Angular的依赖注入系统会校验服务类的构造函数参数,即便你通过useFactory手动实例化服务,Angular仍然会检查构造函数中每个参数是否有对应的注入令牌。你的MyService构造函数中的number类型没有默认的注入令牌,因此触发NG2003错误。
正确解决方法
方法1:使用@Optional()标记参数为可选
通过@Optional()装饰器告诉Angular该参数不需要依赖注入系统提供,我们会通过useFactory手动传入:
// my-service.service.ts import { Injectable, Optional } from '@angular/core'; @Injectable() export class MyService { constructor( @Optional() private n: number ) { console.log(this.n); } }
模块代码无需修改,这种方式适合快速解决简单场景,无需额外定义令牌。
方法2:使用注入令牌(符合Angular DI规范)
这是更规范的做法,适合参数需要在多个地方复用或后续可能调整的场景:
- 首先在服务文件中定义注入令牌:
// my-service.service.ts import { InjectionToken, Injectable, Inject } from '@angular/core'; // 定义注入令牌 export const MY_SERVICE_PARAM = new InjectionToken<number>('MyService初始化参数'); @Injectable() export class MyService { constructor( @Inject(MY_SERVICE_PARAM) private n: number ) { console.log(this.n); } }
- 在模块中提供令牌的值,并在
useFactory中声明依赖:
// my-module.module.ts import { NgModule } from '@angular/core'; import { MyService, MY_SERVICE_PARAM } from './my-service.service'; @NgModule({ providers: [ // 提供令牌对应的参数值 { provide: MY_SERVICE_PARAM, useValue: 2 }, { provide: MyService, // 通过deps获取注入的参数值 useFactory: (param: number) => new MyService(param), deps: [MY_SERVICE_PARAM] }, ], }) export class MyModule {}
方法3:移除@Injectable()装饰器
如果该服务只会通过useFactory手动实例化,不需要Angular依赖注入系统管理,可以直接去掉@Injectable()装饰器,这样Angular就不会对构造函数做DI校验:
// my-service.service.ts export class MyService { constructor( private n: number ) { console.log(this.n); } }
模块代码保持不变即可。
关于临时解决方法的说明
你使用的@Inject('')是一种不规范的hack:空字符串作为令牌没有实际意义,Angular DI系统找不到对应的提供者,但因为你是手动实例化服务,运行时不会报错。但这种方法存在隐患——如果后续该服务被其他地方通过DI注入,会直接抛出找不到提供者的错误,完全不符合Angular的DI设计规范,不建议使用。
内容的提问来源于stack exchange,提问作者undefined
相关产品推荐
相关产品推荐

