自制方法装饰器擦除所有元数据,我该如何解决?

Posted

技术标签:

【中文标题】自制方法装饰器擦除所有元数据,我该如何解决?【英文标题】:Selfmade method decorator erasing all metadata, how I can resolve it? 【发布时间】:2020-09-25 23:05:48 【问题描述】:

我正在使用 NestJS 和 nestjs/swagger 模块来编写简单的 api 文档,但我遇到了麻烦,因为我需要验证来自我的服务的响应。

这就是我创建自己的方法装饰器的原因,但是当我使用它时遇到了很大的麻烦 - 来自另一个装饰器的所有元数据都丢失了,并且 swagger 模块无法显示良好的文档。

我的装饰器代码

export function validate(classValidatorEntity: any): MethodDecorator 
  return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => 
    const origMethod = descriptor.value;
    descriptor.value = async function() 
      const result = await origMethod.apply(this, arguments);
      console.log(result); // validationFunc(result) in original method
      return result;
    ;
  ;

以及一些控制器方法的代码示例

  @Post('test')
  @ApiOkResponse(
    type: someResDto
  )
  @ResponseValidator(ActualizeFlightQueueResponseDto)
  public async test(@Body() body: someReqDto): Promise<someResDto> 
    return result: true
  

如果我的装饰器在顶部(第一个) - 所有元数据都丢失了。 如果我的 daecorator 是最后一个 - 我会从 @Body() 装饰器中丢失数据....

我不知道该做什么,以及我需要如何重写我自己的装饰器。

【问题讨论】:

【参考方案1】:

元数据与特定的descriptor.value 关联,您必须将与origMethod 关联的元数据重新应用到新的descriptor.value

首先定义一个元数据copyMetadata方法

const copyMetadata = (source: Object, target: Object): void => 
  for (const key of Reflect.getMetadataKeys(source)) 
    Reflect.defineMetadata(key, Reflect.getMetadata(key,source), target);
  

然后将元数据重新应用到新的descriptor.value

export function validate(classValidatorEntity: any): MethodDecorator 
  return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => 
    const origMethod = descriptor.value;
    descriptor.value = async function() 
      const result = await origMethod.apply(this, arguments);
      console.log(result); // validationFunc(result) in original method
      return result;
    ;
    copyMetadata(origMethod, descriptor.value);
  ;

【讨论】:

以上是关于自制方法装饰器擦除所有元数据,我该如何解决?的主要内容,如果未能解决你的问题,请参考以下文章

如何从方法装饰器访问类元数据

自制软件的 data_directory 在哪里?或者对于 postgresql 或者我该如何解决错误,“”global/pg_filenode.map“:没有这样的文件或目录”?

从 Map 擦除后访问指针

如何解决自制软件发生的这个问题?

如何解2元一次方程

如何解锁 sqlplus 用户?