NestJs:将服务(或其他任何东西)注入导入的模块

阿列扬德罗

有没有一种比下面更好的方法将服务或组件注入到导入的模块中?

export interface AmqpInterceptor{
  after(message:any):Promise<void>;
}

export class AmqpInterceptors extends Array<AmqpInterceptor>{

}

//generic library module
@Module({
  providers:[{
    provide: AmqpInterceptors,
    useValue: []
  }]
}
export class AMQPModule implements OnModuleInit{
  static register(options: AMQPOptions): DynamicModule {
    const providers = options.providers || []
    return {
      module: AMQPModule,
      providers: [
        ...providers,
        OtherProvider
      ]
    }
  }
}

//end user module
@Module({
  imports: [
    AMQPModule.register(({
      // I had to create a factory method to pass providers as an argument.
      // I would think that it is not a good practice
      providers: [{
        provide:AmqpInterceptors,
        useValue:[MyCustomInterceptor]
      }]
    })
  ],
  providers: [
    
  ]
})
export class QueueModule {

}

当前有效的解决方案:我在通用模块中声明了一个默认的空数组,并在工厂方法中声明了允许在模块构造中传递自定义值的工厂方法。(在我最幸福的世界中,我声明了一个接口的多个实例,然后DI收集了所有这些实例,但是我认为这在NestJs中实际上是不可能的)

纳坦·迪奇(Natan Deitch)

您可以使用@ golevelup / nestjs-discovery之类的软件包来帮助您。

基本上,您必须执行以下操作:

// AMQP模块

// amqp-interceptor.decorator.ts

import { SetMetadata } from '@nestjs/common';

export function AmqpInterceptor() {
  return SetMetadata('AMQP_INTERCEPTOR', true)
}

// amqp-explorer.ts

import { OnModuleInit } from '@nestjs/common'

@Injectable()
export class AmqpExplorer implements OnModuleInit {
  constructor(
    private readonly discoveryService: DiscoveryService,
  ) {}

  async onModuleInit(): Promise<void> {
      const amqpInterceptorProviders = await this.discoveryService.providers('AMQP_INTERCEPTOR')

      // you can store this list, to be queried by some
      // other provider to use interceptors, etc.
  }
}

// amqp.module.ts

@Module({ providers:[AmqpExplorer]})
export class AMQPModule { }

//最终用户模块

// end-user.module.ts

@Module({ imports:[AMQPModule], providers: [SomeAmqpInterceptor] })
export class EndUserModule { }

// some-amqp.interceptor.ts

@Injectable()
@AmqpInterceptor()
export class SomeAmqpInterceptor {
  run(): void { console.log('intercepting') }
}

Obs:

  • 拦截器装饰器:您可以添加任何可以帮助您改善api的参数
  • 我建议使用此列表(提供程序列表),而不是将经过修饰的提供程序注入模块中,因为我不知道您打算如何使用它们。这样,您就有了一个提供程序列表,并且可以调用每个提供程序。
  • AMQP_INTERCEPTOR 字符串可能会与其他一些元数据发生冲突,这是一个好习惯,在模块中添加更具体的内容以避免两个元数据具有相同的元数据
  • 稍后调用拦截器:
import { ExternalContextCreator } from '@nestjs/core/helpers/external-context-creator'

export class Runner {
  constructor(
    private readonly handler: DiscoveredMethodWithMeta,
    private readonly externalContextCreator: ExternalContextCreator,
  ) { }

  run(): void {
    const handler = this.externalContextCreator.create(
      this.handler.discoveredMethod.parentClass.instance,
      this.handler.discoveredMethod.handler,
      this.handler.discoveredMethod.methodName,
    )

    const handlerResult = await handler(content)
  }
  • 没有在本地运行,但是我认为这是一个很好的起点

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

黑客能否将任何东西注入到/ var / www / html之外的服务器

如何在 Ubuntu 上设置邮件服务器(postfix 或其他任何东西)?

背景移动远比其他任何东西都快

NestJS。无法从其他模块注入存储库

angular filter:{v:0} 不过滤任何东西。其他值正常工作

AOT和汇总:仅捆绑main.js,不捆绑其他任何东西

除了aws ec2 vncserver看不到终端或其他任何东西

如何用继承或模板(或其他任何东西)替换此宏?

如何替换Kubuntu中的Application Launcher图标(用其他任何东西替换“ K”)?

在不移动其他任何东西的情况下增加div

是否可以在Unity或其他方式中以自然方式为任何东西设置动画?

导航视图XML不允许我与其他任何东西交互

Jquery alert() 可以工作,但不能 addclass() 或其他任何东西

正则表达式匹配其他任何东西,但

使用模块导出将组件(服务)注入其他组件(服务)

无法将任何东西从bit.dev导入我的React项目

在使用 pyinstaller 或其他任何东西将 py 编译为 exe 后,是否可以让控制台仅在特定时间处于活动状态?

Spring 3.2 @Configurable和@Autowire无法注入任何东西

从其他模块导入

允许 delphi 在变量中使用 0x56。除了将十六进制转换为其他东西之外,我似乎在互联网上找不到任何东西

我想在悬停事件上为按钮添加边框而不移动按钮或其他任何东西

.NET 3.5之外的其他任何东西都无法在C#项目中命中断点

Win32本机(API或其他任何东西)读取当前计算机的地理位置?

数组的对象与设置器(或其他任何东西)一起使用时显示错误“ Java返回:1”

在 Python 中使用 XPATH(或其他任何东西)使用深度优先搜索方法遍历 XML 文件

PHPUnit:在功能测试期间使用 dbunit 或其他任何东西修改数据库条目

我可以在一维数据帧上使用 apply() 或其他任何东西来构建数据帧列表吗?

AngularJS-来自其他模块的错误注入服务

我可以像其他任何库一样将JointJS作为AngularJS模块注入吗?