NestJs monorepo 共享库注入

Posted

技术标签:

【中文标题】NestJs monorepo 共享库注入【英文标题】:NestJs monorepo shared lib injection 【发布时间】:2020-08-23 04:48:36 【问题描述】:

我有 NestJS 应用程序,其中几个微服务存储在单个存储库中(monorepo 方法)。

AccessControl 模块存储在libs 中,应该在多个微服务之间共享。它有AccessControlModule.ts 文件

@Global()
@Module(
  providers: [
    
      provide: 'CONNECTION1',
      useFactory: (configService: ConfigService) => 
        return ClientProxyFactory.create(
          configService.getRMQConnection(),
        );
      ,
      inject: [ConfigService],
    ,
    ACGuard,
  ],
  exports: [ACGuard],
  imports: [ConfigModule],
)
export class AccessControlModule implements OnModuleDestroy 
  constructor(
    @Inject('CONNECTION1')
    protected readonly orgConnection: ClientProxy,
  ) 

  onModuleDestroy(): any 
    this.orgConnection.close();
  

这个文件负责模块描述,它为另一个微服务创建连接并提供给ACGuard服务。 ACGuard.ts

@Injectable()
export class ACGuard implements CanActivate 
  constructor(
    private readonly reflector: Reflector,
    private config: ConfigService,
    @Inject('CONNECTION1')
    private readonly userConnection: ClientProxy;
  ) 

  public async canActivate(context: ExecutionContext): Promise<boolean> 
   // do some stuff 
  

这部分本身编译良好,逻辑上工作正常。当我尝试将其注入其中一个微服务时,问题就开始了。我像往常一样将AccessControlModule 添加到某个模块的import 部分。例如KioskModule:

@Module(
  imports: [
    ...
    AccessControlModule
  ],
  providers: [
    ...
    KiosksResolver
  ]
)
export class KiosksModule 

由于AccessControlModule 标记为Global 并导出ACGuard,我希望它可以注入到我的提供程序中。

@Resolver('Kiosk')
export class KiosksResolver 
  ...

  @UseGuards(ACGuard)
  @Query()
  kiosks() 
    // ...
  

   ... 

但是这段代码在编译步骤出现错误:

[Nest] 9964 - 05/07/2020, 9:33:02 PM [ExceptionHandler] Nest 无法解析 ACGuard 的依赖项(Reflector、ConfigService、?)。请确保索引 [2] 处的参数 CONNECTION1 在 KiosksModule 上下文中可用。

另一方面,如果我将它注入KiosksResolver 的构造函数,应用程序构建成功。

我将不胜感激任何帮助和想法,谢谢!

【问题讨论】:

【参考方案1】:

我解决这个问题的方法是在AccessControlModule.ts 中导出CONNECTION1 提供程序。

@Module(
  providers: [
    
      provide: 'CONNECTION1',
      useFactory: (configService: ConfigService) => 
        return ClientProxyFactory.create(
          configService.getRMQConnection(),
        );
      ,
      inject: [ConfigService],
    ,
    ACGuard,
  ],
  exports: [ACGuard, 'CONNECTION1'],
  imports: [ConfigModule],
)
export class AccessControlModule ...

通过此导出KioskModule 创建它自己的ACGuard,但在此处提供从AccessControlModule 导出的连接。 我不清楚为什么 KioskModule 没有得到从 AccessControlModule 导出的 ACGuard 的构建实例,但请尝试再次构建它。

【讨论】:

以上是关于NestJs monorepo 共享库注入的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有不同库共享变量的 monorepo 中管理 SCSS 样式表?

通过库共享时未注册 NestJS 自定义 PassportStrategy

在 Ngrx-nx Monorepo 中管理共享样式和资产

如何在 Monorepo 中的 VueJS 项目之间共享组件

如何使用 Heroku 上的库部署 monorepo

如何在多个库之间共享上下文?