为 CQRS 实施包装 Masstransit 是一个好习惯吗?
Is it a good practice to wrap Masstransit for CQRS implementation?
我宁愿有一个单独的 CommandBus
和 EventBus
以及 ICommandHandler<TCommand>
和 IEventHandler<TCommand>
这样 OrderEventHandler
class 看起来像:
public class OrderEventHandler :
IEventHandler<OrderPlaced>,
IEventHandler<OrderRegistrantAssigned>,
IEventHandler<OrderTotalsCalculated>,
IEventHandler<OrderConfirmed>,
IEventHandler<OrderExpired>,
IEventHandler<SeatAssignmentsCreated>,
IEventHandler<SeatAssigned>,
IEventHandler<SeatAssignmentUpdated>,
IEventHandler<SeatUnassigned>
{
public void Handle(OrderPlaced @event){...}
.
.
.
}
一个可能的解决方案是在 Masstransit
基础设施和我的 CQRS
之间提供一个采用者(比如 ConsumerToHandlerAdopter<T>
它只公开我通常需要的上下文细节)。
但是由于我是 Masstransit
的新手,我无法理解以后可能需要处理的问题。
所以我的问题是:
通常是否值得包装 Masstransit 以便我处理自己的基础设施?
我们使用 MassTransit 广泛实施 CRQS,但仅用于命令处理。
多次讨论了不使用消息传递基础结构来同步写入和读取模型的原因。主要原因是您有机会坚持更改而不发布事件,因为这是基础架构的两个不同部分。除非你使用DTC之类的东西,否则你将无法保证模型之间的一致性。
此外,在这一点上,我们也希望远离 "God handler" classes。 MassTransit 特别擅长通过将每个消费者分离到单独的 class.
来执行 SRP(单一责任原则)
对于一般领域基于事件的集成(反应式事件处理),我们也使用 MassTransit。
你也可以有实现多个消息接口的事件,这样你会有更全面的事件处理:
public interface CustomerRegistered
{
string FullName { get; }
}
public interface OrderPlaced
{
string Reference { get; }
List<OrderLine> Lines { get; }
}
public class NewCustomerOrderedStuff : CustomerRegistered, OrderPlaced
{
...
}
public class CustomerRegisteredConsumer : IConsumer<CustomerRegistered>
public class OrderPlacedConsumer : IConsumer<OrderPlaced>
每个消费者都有不同的关注点,可以生活在一个单独的有界上下文(服务)中。
我宁愿有一个单独的 CommandBus
和 EventBus
以及 ICommandHandler<TCommand>
和 IEventHandler<TCommand>
这样 OrderEventHandler
class 看起来像:
public class OrderEventHandler :
IEventHandler<OrderPlaced>,
IEventHandler<OrderRegistrantAssigned>,
IEventHandler<OrderTotalsCalculated>,
IEventHandler<OrderConfirmed>,
IEventHandler<OrderExpired>,
IEventHandler<SeatAssignmentsCreated>,
IEventHandler<SeatAssigned>,
IEventHandler<SeatAssignmentUpdated>,
IEventHandler<SeatUnassigned>
{
public void Handle(OrderPlaced @event){...}
.
.
.
}
一个可能的解决方案是在 Masstransit
基础设施和我的 CQRS
之间提供一个采用者(比如 ConsumerToHandlerAdopter<T>
它只公开我通常需要的上下文细节)。
但是由于我是 Masstransit
的新手,我无法理解以后可能需要处理的问题。
所以我的问题是: 通常是否值得包装 Masstransit 以便我处理自己的基础设施?
我们使用 MassTransit 广泛实施 CRQS,但仅用于命令处理。
多次讨论了不使用消息传递基础结构来同步写入和读取模型的原因。主要原因是您有机会坚持更改而不发布事件,因为这是基础架构的两个不同部分。除非你使用DTC之类的东西,否则你将无法保证模型之间的一致性。
此外,在这一点上,我们也希望远离 "God handler" classes。 MassTransit 特别擅长通过将每个消费者分离到单独的 class.
来执行 SRP(单一责任原则)对于一般领域基于事件的集成(反应式事件处理),我们也使用 MassTransit。
你也可以有实现多个消息接口的事件,这样你会有更全面的事件处理:
public interface CustomerRegistered
{
string FullName { get; }
}
public interface OrderPlaced
{
string Reference { get; }
List<OrderLine> Lines { get; }
}
public class NewCustomerOrderedStuff : CustomerRegistered, OrderPlaced
{
...
}
public class CustomerRegisteredConsumer : IConsumer<CustomerRegistered>
public class OrderPlacedConsumer : IConsumer<OrderPlaced>
每个消费者都有不同的关注点,可以生活在一个单独的有界上下文(服务)中。