如何附加带有依赖项注入的类级别过滤器?

时间:2019-05-15 12:59:02

标签: nestjs

我正在尝试使用过滤器捕获特定控制器内的故障。我的过滤器需要访问另一个服务(以保存在db中),而且我不确定如何使用具有依赖项注入的类级别过滤器(DI,以便该过滤器可以访问该服务)。

我目前已经从使用装饰器UseFilters的控制器传递了服务,但意识到装饰器不共享相同的作用域。

@UseFilters(new UnprocessableEntityExceptionFilter(myService))
@Catch(UnprocessableEntityException)
export class UnprocessableEntityExceptionFilter implements ExceptionFilter {
  constructor(private readonly requestsService: RequestsService) { }

  async catch(exception: UnprocessableEntityException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const status = exception.getStatus();
    const body = exception.message;

    response.status(status).json(body);
    await this.requestsService.create(request, response, body);
  }
}

我想像这样在类级别使用此过滤器...

@UseFilters(new UnprocessableEntityExceptionFilter())
export class EventsController {
  constructor() { }

  @Get()
  async get() {
   ...
  }

但是我显然无法创建UnprocessableEntityExceptionFilter的新实例,因为它需要依赖项注入。

我了解文档告诉我们,当过滤器具有依赖项注入时要使用此方法,但我不希望此过滤器是全局的。

  
@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})

1 个答案:

答案 0 :(得分:0)

我最终使用了这个

public sealed partial class ShareTargetPage : Page, IViewFor<ShareTargetViewModel>
{
    public event EventHandler<SharedDataEventArg> Navigated;

    private void OnNavigated(SharedDataEventArg e)
    {
        Navigated?.Invoke(this, e);
    }

    private IObservable<EventPattern<SharedDataEventArg>> navigated;

    public ShareTargetPage()
    {
        navigated = Observable.FromEventPattern<SharedDataEventArg>(h => Navigated += h, h => Navigated -= h);

        InitializeComponent();
        ViewModel = new ShareTargetViewModel();

        this.WhenActivated(disposable =>
        {
            navigated
                .Select(x=> x.EventArgs)
                .InvokeCommand(this, x => x.ViewModel.ParseCommand)
                .DisposeWith(disposable);
        });
    }

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        var operation = (e.Parameter as ShareOperation);
        OnNavigated(new SharedDataEventArg(operation, await operation?.Data?.GetWebLinkAsync()));

    }

    public static readonly DependencyProperty ViewModelProperty = DependencyProperty
        .Register(nameof(ViewModel), typeof(ShareTargetViewModel), typeof(ShareTargetPage), new PropertyMetadata(null));

    public ShareTargetViewModel ViewModel
    {
        get => (ShareTargetViewModel)GetValue(ViewModelProperty);
        set => SetValue(ViewModelProperty, value);
    }

    object IViewFor.ViewModel
    {
        get => ViewModel;
        set => ViewModel = (ShareTargetViewModel)value;
    }
}