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

时间:2018-08-07 19:24:15

标签: node.js typescript nestjs typeorm

我需要访问TypeOrmModule函数(重要说明:不作为intercept参数!)内部的服务(由Nest 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$;
  }
}

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

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

  @Get()
  @UseInterceptors(new PaginationInterceptor(Customer))
  async getAll() {
    // stuff...
  }

2 个答案:

答案 0 :(得分:3)

关于依赖注入(如果您确实想要/需要),我想使用mixin类可以解决问题。请参阅v4 documentation(高级> 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);
}

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

@UseInterceptors(mixinPaginationInterceptor(YourEntityClass))

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


您还可以使用getRepository中的typeorm(传递实体类)。 这不是DI ,因此,它将要求您spyOn getRepository函数来进行适当的测试。


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

答案 1 :(得分:0)

您可以使用NestFactory创建一个NestApplication实例以注入任何提供程序或控制器。

示例

假设您的AppModule中有以下提供者:

providers: [{provide: 'MyToken', useValue: 'my-value'}]

然后,您可以通过以下方式在任何地方注入此提供程序:

// Creates an instance of the NestApplication
const application = await NestFactory.create(AppModule);

// Retrieves an instance of either injectable or controller available anywhere, otherwise, throws exception.
const myValue = application.get('MyToken');

console.log(myValue); // -> my-value