在自定义拦截器中访问 Nest“注入器”

gre*_*emo 4 node.js typescript typeorm nestjs

我需要访问函数TypeOrmModule内部的服务(由 Nest 提供)intercept(重要说明:不是作为 constructor 参数!!!),因为它取决于传递的选项(entity在这种情况下)。

服务注入令牌由getRepositoryToken函数提供。

export class PaginationInterceptor {
  constructor(private readonly entity: Function) {}

  intercept(context: ExecutionContext, call$: Observable<any>): Observable<any> {
    // Here I want to inject the TypeORM repository.
    // I know how to get the injection token, but not HOW to
    // get the "injector" itself.
    const repository = getRepositoryToken(this.entity);

    // stuff...

    return call$;
  }
}
Run Code Online (Sandbox Code Playgroud)

Nest 中是否有“服务容器”的概念?这个github 问题对我没有帮助。

示例用法(控制器操作):

  @Get()
  @UseInterceptors(new PaginationInterceptor(Customer))
  async getAll() {
    // stuff...
  }
Run Code Online (Sandbox Code Playgroud)

Vin*_*OPS 6

关于依赖注入(如果你真的想要/需要它),我想使用mixin类可以解决问题。请参阅v4 文档(高级 > Mixin 类)。

import { NestInterceptor, ExecutionContext, mixin, Inject } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Observable } from 'rxjs';
import { Repository } from 'typeorm';

export function mixinPaginationInterceptor<T extends new (...args: any[]) => any>(entityClass: T) {
  // declare the class here as we can't give it "as-is" to `mixin` because of the decorator in its constructor
  class PaginationInterceptor implements NestInterceptor {
    constructor(@Inject(getRepositoryToken(entityClass)) private readonly repository: Repository<T>) {}

    intercept(context: ExecutionContext, $call: Observable<any>) {
      // do your things with `this.repository`
      return $call;
    }
  }

  return mixin(PaginationInterceptor);
}
Run Code Online (Sandbox Code Playgroud)

免责声明:这是有效的 TypeScript 代码,但我没有机会在实际项目中对其进行测试,因此可能需要进行一些返工。这个想法是这样使用它:

@UseInterceptors(mixinPaginationInterceptor(YourEntityClass))
Run Code Online (Sandbox Code Playgroud)

如果您对代码有任何疑问,请告诉我。但我认为有关的文档mixin非常好!


OR您也可以使用getRepositoryfrom typeorm(传递实体类)。这不是 DI,因此,它会迫使您使用spyOn该getRepository函数以进行适当的测试。


关于容器,我几乎可以肯定访问它的唯一方法是使用Execution Context,正如 Kim 所指出的。