Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good practice to wrap Masstransit for CQRS implementation? [closed]

I would rather have a separate CommandBus and EventBus and also ICommandHandler<TCommand> and IEventHandler<TCommand> so that an OrderEventHandler class looks like:

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){...}
    .
    .
    .
}

A possible solution can be providing an adopter between Masstransit infrastructure and my CQRS(like ConsumerToHandlerAdopter<T>which only exposes the context details I generally need ).

But since I'm new to Masstransit, I can't get my head around the issues I might have to deal with later.

So my question is: Does it generally worth to wrap Masstransit so that I deal with my own Infrastructure?

like image 211
Mohsen Avatar asked Sep 11 '17 10:09

Mohsen


1 Answers

We use MassTransit to implement CRQS extensively, but only for command handling.

The reason for not to use messaging infrastructure to synchronise write and read models are discussed many times. The main reason there is that you have a chance of persisting a change and not publishing an event, because these are two different pieces of infrastructure. Unless you use something like DTC, you will not be able to guarantee the consistency among models.

Also, at this point we also prefer to stay away from the "God handler" classes. MassTransit is particularly good at enforcing the SRP (single responsibility principle) by separating each consumer to a separate class.

For general domain event-based integration (reactive event processing), we also use MassTransit.

You can also have events that implement more than one message interface and by this you will have more comprehensive event processing:

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>

And each of those consumers will have different concern and can live in a separate bounded context (service).

like image 181
Alexey Zimarev Avatar answered Nov 09 '22 11:11

Alexey Zimarev