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

NestJS继承类场景下基于属性的依赖注入失效如何解决

问题根因
  • NestJS 的依赖注入仅会对被 @Injectable() 装饰的类进行依赖处理,你当前的 BaseService 没有被 @Injectable() 修饰,也没有通过构造函数/属性装饰器声明依赖注入规则,因此 utilsProvider 无法被自动赋值,始终为 undefined。
  • 你之前将 BaseService 封装为独立模块引入不生效的原因是:BaseService 作为抽象父类,实例化是由子类完成的,单独将其注册为 provider 不会处理继承场景下的依赖注入。
解决方案

方案1:构造函数透传依赖(官方推荐)

该方案依赖关系清晰,类型安全,适合绝大多数场景。

第一步:修改 BaseService 代码

import { Injectable, OnModuleInit } from '@nestjs/common';
import { Model } from 'mongoose';
import { UtilsProvider } from 'src/utils/utils.service';
import { DocumentType } from '@typegoose/typegoose'; // 注意导入缺失的类型

@Injectable()
export class BaseService<MongooseModelT extends Record<string | number, any>>
  implements OnModuleInit
{
  constructor(
    private mongooseModel: Model<DocumentType<MongooseModelT>>,
    // 将UtilsProvider加入构造参数
    private utilsProvider: UtilsProvider
  ) {}
  
  async transform(){
    // 可直接正常使用this.utilsProvider
  }
}

第二步:修改子类代码,透传注入的依赖

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { BaseService } from 'xxx/base.service'; // 替换为实际路径
import { CompanyDocument } from './schemas/company.schema';
import { CreateCompanyDto } from './dto/create-company.dto';
import { UtilsProvider } from 'src/utils/utils.service';

@Injectable()
export class CompaniesService extends BaseService<CompanyDocument> {
  constructor(
    @InjectModel(Company.name) private companyModel: Model<CompanyDocument>,
    // 注入全局的UtilsProvider
    utilsProvider: UtilsProvider
  ) {
    // 透传给父类构造函数
    super(companyModel, utilsProvider);
  }

  create(createCompanyDto: CreateCompanyDto) {
    return this.companyModel.create(createCompanyDto);
  }
}

方案2:父类属性注入(适合父类依赖较多的场景)

该方案无需修改子类代码,通过属性装饰器自动完成注入。

仅需修改BaseService代码,添加@Inject装饰器即可

import { Inject, OnModuleInit } from '@nestjs/common';
import { Model } from 'mongoose';
import { UtilsProvider } from 'src/utils/utils.service';
import { DocumentType } from '@typegoose/typegoose';

export class BaseService<MongooseModelT extends Record<string | number, any>>
  implements OnModuleInit
{
  // 声明该属性需要Nest注入UtilsProvider
  @Inject(UtilsProvider)
  private utilsProvider: UtilsProvider; 

  constructor(private mongooseModel: Model<DocumentType<MongooseModelT>>) {}
  
  async transform(){
    // 可直接正常使用this.utilsProvider
  }
}
注意事项
  • 请确保你已经在根模块 AppModule 的 imports 数组中加入了 UtilsModule,全局模块也需要在根模块导入一次才能全局生效。
  • 如果你的 UtilsModule 没有加 @Global() 装饰器,需要在所有继承 BaseService 的子类所属模块的 imports 数组中导入 UtilsModule。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 07:27:03