Как работать с внедрением на основе свойств при расширении класса

#typescript #nestjs

Вопрос:

У меня есть определенный случай использования, когда мне нужно внедрить поставщика на основе свойств в родительский класс, но каким-то образом класс поставщика не захвачен внедрением зависимостей, поэтому возвращается как неопределенный.

Ниже приведен мой родительский класс, который в основном содержит некоторые функции для разбиения на страницы, сортировки и т.д. Для обработки запросов rest. Это не модуль, возможно, в этом причина.

Одна вещь, которая здесь может быть неправильной, заключается в том, что BaseService не является модулем NestJS, это просто автономный файл службы, экспортирующий этот класс.

 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
  }
}
 

Пример службы, расширяющей этот базовый сервис,

 @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, так как, возможно, именно поэтому он не фиксирует внедрение зависимостей, но это тоже не сработало.

Ответ №1:

Из документов,

«…вы можете использовать декоратор @Inject() на уровне свойств».

Изменение базового класса на следующий должно устранить проблему:

 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
  }
}
 

Кажется, здесь есть досадная разница между инъекцией на основе свойств и конструктора, которая больше нигде не упоминается.