扩展 class 时如何使用基于 属性 的注入
How to work with Property Based Injection when extending class
我有一个特定的用例,我需要在父 class 中进行基于 属性 的提供者注入,但不知何故,提供者 class 未被依赖项注入捕获,因此返回为未定义。
下面是我的父 class,它基本上包含一些功能来执行分页、排序等以处理其余查询。这不是一个模块,也许是这个原因。
这里可能有一点不对,BaseService 不是 NestJS 模块,它只是导出此 class.
的独立服务文件
import { Model } from 'mongoose';
import { UtilsProvider } from 'src/utils/utils.service';
export class BaseService<MongooseModelT extends Record<string | number, any>>
implements OnModuleInit
{
private utilsProvider: UtilsProvider; // always returned undefined
constructor(private mongooseModel: Model<DocumentType<MongooseModelT>>) {}
async transform(){
... Some logic that uses UtilsProvider
}
}
扩展此 BaseService 的示例服务,
@Injectable()
export class CompaniesService extends BaseService<CompanyDocument> {
constructor(
@InjectModel(Company.name) private companyModel: Model<CompanyDocument>,
) {
super(companyModel);
}
create(createCompanyDto: CreateCompanyDto) {
return this.companyModel.create(createCompanyDto);
}
}
公司模块,
import { Module } from '@nestjs/common';
import { CompaniesService } from './companies.service';
import { CompaniesController } from './companies.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { Company, CompanySchema } from './schemas/company.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: Company.name, schema: CompanySchema }]),
],
controllers: [CompaniesController],
providers: [CompaniesService],
})
export class CompaniesModule {}
UtilsProvider 是从一个模块中导出的,它在全局范围内,
@Global()
@Module({
providers: [UtilsProvider],
exports: [UtilsProvider],
})
export class UtilsModule {}
我还尝试用模块包装 BaseService 并将其导入到 app.module.ts 文件中,因为这可能就是它没有捕获依赖项注入的原因,但这也不起作用。
来自docs,
"...you can use the @Inject() decorator at the property level."
将您的基础 class 更改为以下应该可以解决问题:
import { Inject } from '@nestjs/common';
import { Model } from 'mongoose';
import { UtilsProvider } from 'src/utils/utils.service';
export class BaseService<MongooseModelT extends Record<string | number, any>>
implements OnModuleInit
{
@Inject(UtilsProvider) // Must have @Inject
private utilsProvider: UtilsProvider; // Will now be defined
constructor(private mongooseModel: Model<DocumentType<MongooseModelT>>) {}
async transform(){
... Some logic that uses UtilsProvider
}
}
属性 和基于构造函数的注入之间似乎有一个不幸的区别,其他地方都没有提到。
我有一个特定的用例,我需要在父 class 中进行基于 属性 的提供者注入,但不知何故,提供者 class 未被依赖项注入捕获,因此返回为未定义。
下面是我的父 class,它基本上包含一些功能来执行分页、排序等以处理其余查询。这不是一个模块,也许是这个原因。
这里可能有一点不对,BaseService 不是 NestJS 模块,它只是导出此 class.
的独立服务文件import { Model } from 'mongoose';
import { UtilsProvider } from 'src/utils/utils.service';
export class BaseService<MongooseModelT extends Record<string | number, any>>
implements OnModuleInit
{
private utilsProvider: UtilsProvider; // always returned undefined
constructor(private mongooseModel: Model<DocumentType<MongooseModelT>>) {}
async transform(){
... Some logic that uses UtilsProvider
}
}
扩展此 BaseService 的示例服务,
@Injectable()
export class CompaniesService extends BaseService<CompanyDocument> {
constructor(
@InjectModel(Company.name) private companyModel: Model<CompanyDocument>,
) {
super(companyModel);
}
create(createCompanyDto: CreateCompanyDto) {
return this.companyModel.create(createCompanyDto);
}
}
公司模块,
import { Module } from '@nestjs/common';
import { CompaniesService } from './companies.service';
import { CompaniesController } from './companies.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { Company, CompanySchema } from './schemas/company.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: Company.name, schema: CompanySchema }]),
],
controllers: [CompaniesController],
providers: [CompaniesService],
})
export class CompaniesModule {}
UtilsProvider 是从一个模块中导出的,它在全局范围内,
@Global()
@Module({
providers: [UtilsProvider],
exports: [UtilsProvider],
})
export class UtilsModule {}
我还尝试用模块包装 BaseService 并将其导入到 app.module.ts 文件中,因为这可能就是它没有捕获依赖项注入的原因,但这也不起作用。
来自docs,
"...you can use the @Inject() decorator at the property level."
将您的基础 class 更改为以下应该可以解决问题:
import { Inject } from '@nestjs/common';
import { Model } from 'mongoose';
import { UtilsProvider } from 'src/utils/utils.service';
export class BaseService<MongooseModelT extends Record<string | number, any>>
implements OnModuleInit
{
@Inject(UtilsProvider) // Must have @Inject
private utilsProvider: UtilsProvider; // Will now be defined
constructor(private mongooseModel: Model<DocumentType<MongooseModelT>>) {}
async transform(){
... Some logic that uses UtilsProvider
}
}
属性 和基于构造函数的注入之间似乎有一个不幸的区别,其他地方都没有提到。