Reputation: 162
I have a certain use case where I need to do property-based injection of a provider in a parent class but somehow the provider class is not captured by dependency injection, thus being returned as undefined.
Below is my parent class which basically contains some functions to perform pagination, sorting etc to handle rest queries. This is not a module, maybe this is the reason.
One thing that may be off here is that BaseService is not a NestJS Module, it's just a stand-alone service file that exports this 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
}
}
An example service that extends this 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);
}
}
Companies module,
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 is exported from a module and it is in global scope,
@Global()
@Module({
providers: [UtilsProvider],
exports: [UtilsProvider],
})
export class UtilsModule {}
I also tried wrapping BaseService with a module and importing it in the app.module.ts file since maybe that's why it's not capturing dependency injection, but that did not work either.
Upvotes: 1
Views: 2350
Reputation: 4639
From the docs,
"...you can use the @Inject() decorator at the property level."
Changing your base class to the following should fix the issue:
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
}
}
Seems to be an unfortunate difference here between property and constructor based injection that isn't mentioned anywhere else.
Upvotes: 1