在NestJS中,我必须在entity/model中使用模块服务将数据填充到elastic-search索引中。填充弹性搜索索引逻辑是用Job.service.ts编写的。
我想从模型中出现的后缀钩子中调用来自Job.service.ts的Job.service.ts方法。
这是Job.ts模型/实体的代码-
import { Table, Model, Column, AutoIncrement, PrimaryKey } from "sequelize-typescript";
@Table({ schema: "job", tableName: "job" })
export class Job extends Model<Job> {
@AutoIncrement
@PrimaryKey
@Column
id: number;
@Column
title: string;
@AfterCreate
static async jobAfterCreate(instance, options) {
// <--- need to call job service onCreate method here
}
@AfterUpdate
static async jobAfterUpdate() {}
@AfterDestroy
static async jobAfterDestroy() {}
}这是Job.service.ts的代码-
//imports not added
@Injectable()
export class JobService {
constructor(
@Inject("SEQUELIZE")
private readonly sequelizeInstance: Sequelize,
@Inject(forwardRef(() => ElasticsearchService))
private readonly elasticsearchService: ElasticsearchService,
@InjectModel(Job)
private jobModel: typeof Job
) {}
// here will write logic for updating elastic search index
async onCreate(instance, options){
console.log("ON CREATE INSTANCE:", instance);
console.log("ON CREATE OPTIONS:", options);
}
async onDestroy(instance, options){
console.log("ON DESTROY INSTANCE:", instance);
console.log("ON DESTROY OPTIONS:", options);
}
}我尝试将服务注入Job模型,但没有奏效。而且我不能直接在模型中编写弹性搜索逻辑,因为我需要ElasticsearchService。
发布于 2022-09-27 15:21:23
解决方案是覆盖提供程序。
向模型中注入信息的主要方法是重写注入行为。
首先,您需要添加引用模型中服务的静态属性。
我将以事件发射器为例。
你的模型类
import {Model, Table, Column, AfterCreate} from "sequelize-typescript";
import { EventEmitter2 } from "@nestjs/event-emitter";
@Table()
export class SomeModel extends <SomeModel> {
// this would be your referencing
public static EventEmitter: EventEmitter2;
@Column
public someColumn: string;
@AfterCreate
public static triggerSomeEvent(instance: SomeModel) {
SomeModel.EventEmitter.emit('YourEvent', instance);
}
}要使用模型的模块
现在,我们正在重写默认的注入过程。
import { EntitiesMetadataStorage } from '@nestjs/sequelize/dist/entities-metadata.storage';
import {
getConnectionToken,
getModelToken,
SequelizeModule,
} from '@nestjs/sequelize';
import { EventEmitter2 } from '@nestjs/event-emitter';
// The provider override
const modelInjector: Provider = {
provide: getModelToken(AccountabilityPartnerModel, DEFAULT_CONNECTION_NAME),
useFactory: (connection: Sequelize, eventEmitter: EventEmitter2) => {
SomeModel.EventEmitter = eventEmitter;
if (!connection.repositoryMode) {
return SomeModel;
}
return connection.getRepository(SomeModelas any);
},
inject: [getConnectionToken(DEFAULT_CONNECTION_NAME), EventEmitter2],
};
// Updating the meta information of sequelize-typescript package to handle connection injection in to the model overridden.
EntitiesMetadataStorage.addEntitiesByConnection(DEFAULT_CONNECTION_NAME, [
SomeModel,
]);
// our custom module being used rather than the Sequelize.forFeature([SomeModel])
const someModelModule: DynamicModule = {
module: SequelizeModule,
providers: [modelInjector],
exports: [modelInjector],
};
@Module({
imports: [someModelModule],
providers: [SomeService],
})
export class SomeModule {
}像使用Sequlize.forFeature和InjectModel一样,将模型注入到服务中,如下所示。
@Injectable()
export class SomeService {
constructor(@InjectModel(SomeModel) someModel: typeof SomeModel) {}
public someFunction(data: any) {
this.someModel.EventEmitter.emit('YourEvent', data);
}
}https://stackoverflow.com/questions/72540401
复制相似问题