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

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规范)

这是更规范的做法,适合参数需要在多个地方复用或后续可能调整的场景:

  1. 首先在服务文件中定义注入令牌:
// 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);
  }
}
  1. 在模块中提供令牌的值,并在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:54:24