首页 > 解决方案 > NestJS - 无法将服务注入订阅者

问题描述

我有一个 NestJS 的订阅者来监听任何创建、更新或删除事件 (TypeORM)。当这些事件之一被触发时,我想使用注入服务来创建一个新的修订条目。

但是,似乎我无法在订阅者内部加载依赖项,并且服务返回为未定义

关键文件:

app.module.ts

@Module({
  imports: [
      HttpModule,
      TypeOrmModule.forRoot({
          type: (process.env.DB_TYPE as any) || 'postgres',
          host: process.env.DB_HOST || '127.0.0.1',
          port: (process.env.DB_PORT as any) || 5432,
          username: process.env.DB_USER || 'root',
          password: process.env.DB_PASS || '',
          database: process.env.DB_NAME || 'test',
          entities: [join(__dirname, '**/**.entity{.ts,.js}')],
          synchronize: true,
          logging: 'all',
          logger: 'advanced-console',
          subscribers: [EntityModificationSubscriber],
      }),
      TypeOrmModule.forFeature([
          RevisionEntity,
      ]),
      TerminusModule.forRootAsync({
          // Inject the TypeOrmHealthIndicator provided by nestjs/terminus
          inject: [TypeOrmHealthIndicator, MicroserviceHealthIndicator],
          useFactory: (db, msg) => getTerminusOptions(db, msg),
      }),
      GraphQLModule.forRoot({
          debug: true,
          playground: true,
          typePaths: ['./**/*.graphql'],
      }),
  ],
  controllers: [AppController],
  providers: [
      RevisionService,
      EntityModificationSubscriber,
  ],
})

entity_modification_subscriber.ts

import {EntitySubscriberInterface, EventSubscriber, InsertEvent, RemoveEvent, UpdateEvent} from 'typeorm';
import {RevisionEntity, RevisonEntityStatus} from '../entities/revison.entity';
import {RevisionService} from '../services/revisions.service';
import {Injectable} from '@nestjs/common';

@Injectable()
@EventSubscriber()
export class EntityModificationSubscriber implements EntitySubscriberInterface {

    constructor(private revisionService: RevisionService) {
    }

    // tslint:disable-next-line:no-empty
    afterInsert(event: InsertEvent<any>): Promise<any> | void {
        const revision = new RevisionEntity();

        revision.action = RevisonEntityStatus.Created;
    }

    afterUpdate(event: UpdateEvent<any>): Promise<any> | void {
    }

    // tslint:disable-next-line:no-empty
    afterRemove(event: RemoveEvent<any>) {
        // this.revisionService.createRevisionEntry(revision);
    }
}

标签: node.jstypescriptnestjstypeorm

解决方案


我发现使用 NestJS 将依赖项注入订阅者的唯一方法是不在 TypeORM 配置中注册该订阅者。我将它手动订阅到订阅者构造函数的 TypeORM 连接中。

import { EntitySubscriberInterface, EventSubscriber, InsertEvent, RemoveEvent, UpdateEvent, Connection } from 'typeorm';
    import { RevisionEntity, RevisonEntityStatus } from '../entities/revison.entity';
    import { RevisionService } from '../services/revisions.service';
    import { Injectable } from '@nestjs/common';

    @Injectable()
    @EventSubscriber()
    export class EntityModificationSubscriber implements EntitySubscriberInterface {

        constructor(private readonly connection: Connection, private readonly revisionService: RevisionService) {
            connection.subscribers.push(this); // <---- THIS 
        }

        // tslint:disable-next-line:no-empty
        afterInsert(event: InsertEvent<any>): Promise<any> | void {
            const revision = new RevisionEntity();

            revision.action = RevisonEntityStatus.Created;

            //this.revisionService <- should be working!
        }

        afterUpdate(event: UpdateEvent<any>): Promise<any> | void {
        }

        // tslint:disable-next-line:no-empty
        afterRemove(event: RemoveEvent<any>) {
            // this.revisionService.createRevisionEntry(revision);
        }
    }

然后在你的 app.module 上配置 TypeORM 模块(TypeOrmModule.forRoot)。 删除行

subscribers: [EntityModificationSubscriber],

它解决了我,希望它帮助别人。您可以在一些 NestJS 问题/拉取请求中找到有关该问题的讨论。

https://github.com/nestjs/typeorm/issues/85

https://github.com/nestjs/typeorm/pull/27


推荐阅读