在 NestJS 中,我扩展了 EntitySubscriberInterface 类来创建通用的 EventSubscriber。
我的目标是每次在数据库中插入某些内容时捕获所有 typeorm 存储库事件“beforeInsert”(应该为所有实体触发)。
这段代码之所以有效,是因为该文件保存在 NestJS 中 src 文件夹内的文件夹之一中,并且它的路径是在 NestJS 配置文件中指定的;这样做时,订阅者文件会自动加载。
我的目标是将此文件移动到 npm 包中,以便我可以从 NestJS 应用程序的主逻辑中提取它,然后在需要时初始化它,执行诸如“new ValidatorSubscriber()”之类的操作;
是否可以?因为到目前为止我所有的尝试都失败了。
我尝试在 app.module.ts 中初始化我的 ValidatorSubscriber 类,并且构造函数被正确调用,但订阅者无法工作。
有什么想法吗?
import { EntitySubscriberInterface, EventSubscriber, InsertEvent } from 'typeorm';
@EventSubscriber()
export class ValidatorSubscriber<T> implements EntitySubscriberInterface<T> {
private entitiesMap = new Map();
constructor() {
console.log('EventSubscriber constructor')
import('../db/entities') // get all entities
.then((allEntities: any) => {
for (const prop in allEntities) {
this.entitiesMap.set(prop, allEntities[prop])
}
console.log(allEntities)
});
}
/**
* Called before post insertion.
*/
async beforeInsert(event: InsertEvent<any>): Promise<void> {
console.log(`BEFORE INSERTION, ${JSON.stringify(event.entity)}`)
}
}
如果有人需要它,我设法找到解决方案。
我将 this stackoverflow post 的答案与 fwoelffel 在这里提供的答案 结合起来(参见答案的屏幕截图)。
请记住,InjectConnection 已被弃用,我用它来代替:
constructor(
@Inject(Connection) readonly connection: Connection,
) {
我的解决方案是将 EventSubscriber 放在提供程序中,省略数据源选项中的订阅者。
@Module({
imports: [CustomerModule, TypeOrmModule.forFeature([Cart, Customer, Product])],
controllers: [CartController],
providers: [CartService, CustomerCartSubscriber],
exports: [CartService]
})
CustomerCartSubscriber 的内部(重点是在构造函数中使用@Inject):
@EventSubscriber()
export class CustomerCartSubscriber implements EntitySubscriberInterface<Customer> {
constructor(
@Inject(CartService) public readonly cartService: CartService,
@Inject(DataSource) dataSource: DataSource
) {
dataSource.subscribers.push(this);
}
listenTo() {
return Customer;
}
async beforeInsert(event: InsertEvent<Customer>) {
await this.cartService.createCart(event.entity);
}
}