2017-09-11 96 views
1

我宁愿有一个单独的CommandBusEventBusICommandHandler<TCommand>IEventHandler<TCommand>使得OrderEventHandler类的样子:为CQRS实现打包Masstransit是否是一个好习惯?

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让我处理我自己的基础设施?

回答

2

我们使用MassTransit广泛实现CRQS,但仅限于命令处理。

多次讨论不使用消息传递基础结构来同步写入和读取模型的原因。主要原因是您有机会坚持更改而不发布事件,因为这是两个不同的基础架构。除非您使用DTC之类的东西,否则您将无法保证模型之间的一致性。

此外,在这一点上,我们也宁愿远离“上帝处理”类。 MassTransit通过将每个消费者分为一个独立的类来强化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> 

而且每个消费者都会有不同的问题,并可能生活在一个单独的界上下文(服务)。

+0

感谢万@Alexey Zimarev,我使用rabbitmq作为传输层。我的目的是代表我的聚合在这个事件中,并且每当它们变得一致时,然后通过调用'aggregate.method()'来发布返回的事件。我不需要聚合后他们得到一个特定的状态,所以我可以删除它们。 – Mohsen

+1

我有几个项目,我使用sagas作为聚合。这工作得很好,但它没有单独的读取和写入模型。同时,我对事件存储https://github.com/alexeyzimarev/MassTransit.EventStoreIntegration做了一个传奇持久化,并且通过使用它我可以拥有事件源传奇,使用投影构建读取模型,这些模型通过EventStore连接追赶订阅。 –

+0

我很高兴看到有人做了它。但我想没有一个事件存储(或某种批处理事件发布)的问题是,我可能会发布部分发生的事实,如你所说;如果所有事实都已成功发布(如果适合域),则可以使用检查状态并更改它来进行管理。 – Mohsen

相关问题