NestJS CQRS:(存储库的)依赖注入在处理程序中不起作用

Posted

技术标签:

【中文标题】NestJS CQRS:(存储库的)依赖注入在处理程序中不起作用【英文标题】:NestJS CQRS: (Repository's) Dependency Injection not working in handler 【发布时间】:2022-01-09 19:40:10 【问题描述】:

我是 nodejs 的新手,正在尝试实现 NestJS's CQRS 'recipe'。我有一个Request 范围的服务,QueryBus 注入:

@Injectable(scope: Scope.REQUEST)
export class CustomerService 
  constructor(
    @Inject(REQUEST) private readonly req: Request,
    private readonly queryBus: QueryBus,
  ) 

我已经定义了一个处理程序类CustomerHandler 来处理CustomerQuery

@QueryHandler(CustomerQuery)
export class CustomerHandler implements IQueryHandler<CustomerQuery> 
  constructor(
    private readonly repository: CustomerRepository,
  ) 

  async execute(query: CustomerQuery) 
    const response, id, name = query;
    this.repository.getCustomer(response, id, name);
  

但在执行时我收到一条错误消息:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'getCustomer' of undefined at CustomerHandler.execute 

这意味着,如果我没记错的话,存储库注入失败。 (导致语句 this.repository.getCustomer(response, id, name); 的代码失败)

我已在模块CustomerModuleproviders 数组中添加了我的存储库类CustomerRepository

@Module(
  imports: [Logger, CqrsModule],
  providers: [CustomerService, ...QueryHandlers, CustomerRepository],
  exports: [CustomerService],
)
export class CustomerModule 

这是我的存储库类,供参考:

@Injectable()
export class CustomerRepository 
  constructor(
    @Inject(REQUEST) private readonly req: Request,
  ) 

我在这里遗漏了什么吗?为什么我的存储库类没有被实例化,如果不是这样,为什么处理程序中的存储库注入失败。任何输入将不胜感激:)

我正在关注的文档:https://docs.nestjs.com/recipes/cqrs

我参考的 Github 示例:https://github.com/kamilmysliwiec/nest-cqrs-example

编辑:

处理程序 (CustomerHandler) 无法执行任何类型的注入。我尝试注入记录器(PinoLogger),这导致了类似的问题。所以,看起来,问题不在于CustomerRepository,而在于CustomerHandler

更新:

所以基本上,问题在于每个 CqrsModule 提供程序都是 静态范围,这意味着它们不能依赖于请求范围 提供者。一旦将命令处理程序定义为请求范围 提供程序,CommandBus 或 QueryBus 将无法引用它。 这不是问题,而是背后的设计决策 整个模块。

来源:https://github.com/nestjs/cqrs/issues/60#issuecomment-483288297

@QueryHandler() 不能在请求范围内(来源:评论问题 - NestJS undefined dependencies 并回答相同的 https://***.com/a/61916353/10011503)。

而且,这也是open issue。

【问题讨论】:

@Injectable( scope: Scope.REQUEST ) export class CustomerRepository docs.nestjs.com/fundamentals/injection-scopes#injection-scopes 嗨@MicaelLevi,感谢您的建议,我尝试更改范围,但问题仍然存在。 尝试在 CustomerHandler 中添加 Injectable Decorator 并将处理程序添加到提供程序? 嗨@ShahriarShojib,也尝试使用装饰器,有和没有范围,但仍然导致错误。 如果一切都失败了,尝试使用带有或不带有惰性函数的 Inject 装饰器注入它 【参考方案1】:

阅读nestjs doc,我看到命令和查询处理程序的所有处理程序都是默认范围的解析,因此,处理程序中不提供所有具有请求或临时范围的依赖项。解决方案是注入工厂对象,在必要时解决依赖关系

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于NestJS CQRS:(存储库的)依赖注入在处理程序中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有模拟存储库的 Nestjs 服务测试不起作用

Nest 无法解析存储库的依赖关系

在 NestJS 中使用依赖注入导入 TypeScript 模块

如何将 NestJS 中的服务注入 typeorm 存储库?

nestjs 单元测试 createTestingModule 依赖注入

Nestjs 依赖注入 - 将服务注入服务