在NestJS中手动注册一个typeorm EventSubscriber,而不需要在配置文件中指定

问题描述 投票:0回答:2

在 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)}`)
    }
}
typescript nestjs typeorm typescript-decorator nestjs-config
2个回答
2
投票

如果有人需要它,我设法找到解决方案。

我将 this stackoverflow post 的答案与 fwoelffel 在这里提供的答案 结合起来(参见答案的屏幕截图)。
请记住,InjectConnection 已被弃用,我用它来代替:

constructor(
    @Inject(Connection) readonly connection: Connection,
) {

enter image description here


0
投票

我的解决方案是将 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);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.