如何在故障消费者需要额外参数的情况下处理故障消费者的错误?

How to handle errors with fault consumers where the fault consumer needs additional parameters?

我们在一个类似系统的事件源中使用 MassTransit,我们在该系统中提供供不同客户使用的服务。要求是仅在出现问题时向用户提供反馈,因此我们考虑为客户端使用带有 FaultAddress 的故障消费者。客户端将在他们发送的所有命令上设置故障地址,然后实现故障消费者,只要我们在服务中遇到异常,就会收到一条消息。这是有效的,但问题是我们需要向服务不需要的消息添加一些额外的数据,以便从故障消费者正确路由消息。我的想法是在客户端添加参数,而不是在合同中包含它们。假设我们有一个带有订单消费者 OrderConsumer : IConsumer<IOrder>.

的订单服务

我们在客户端创建了一个class,其中包含订单服务不需要的额外参数。

Order : IOrder {
 string ClientId{get;set;}
}

我希望能够使用 OrderFaultConsumer : IConsumer<Fault<Order>> 但这不起作用,我需要创建 OrderFaultConsumer : IConsumer<Fault<IOrder>> 来代替。当我们查看实际发送的消息时,很容易理解为什么我们需要使用 IOrder

命令信息:

 "messageType": [
    "urn:message:Order",
    "urn:message:IOrder"
  ],

  "message": {
    "ClientId": "..."
  },

故障信息:

  "messageType": [
    "urn:message:MassTransit:Fault[[IOrder]]",
    "urn:message:MassTransit:Fault"
  ],
"message": {
}

我希望故障消息能够保持订单并发送消息:

  "messageType": [
    "urn:message:MassTransit:Fault[[Order]]",
    "urn:message:MassTransit:Fault[[IOrder]]",
    "urn:message:MassTransit:Fault"
  ],
"message": {
    "ClientId": "..."
}

我当然可以将 ClientId 添加到 IOrder 并且它适用于该应用程序。问题是该服务不关心 ClientId,另一个客户端可能需要一些其他数据,如 EmailAddress 才能正确路由错误消息。

Fault<T> 根据消费者获取 T 通用参数,发生故障的地方。如果消费者实施 IConsumer<IOrder> - 故障事件将具有 Fault<IOrder> 合同。

如果您不想更改合同,请将您需要的数据放入headers。 FaultFault<T> 事件获取负载中的所有内容。

我也宁愿避免对消息接口使用 I 前缀。这样做你什么也得不到,但它会造成混乱。这些是消息合同。接口只是定义它们的一种方式。