5
votes

Background

We are trying to introduce a new architectural pattern in our company and are considering CQRS with Event Sourcing using a Service Bus. Technologies we are currently developing our POC with are NServiceBus, Event Store, and MSMQ. We would like to have a single endpoint in NServiceBus defined with two different transports, MSMQ for our commands and Event Store for our events. The current state of our enterprise does not permit us to easily switch everything to Event Store presently as we have significant investment in our legacy apps using MSMQ, which is a reason why we are considering the hybrid approach.

Question

Is it possible to create a single NServiceBus endpoint that uses different transports? If yes, how? If no, what alternatives are there?

1

1 Answers

3
votes

Aaron,

I think the best option would be to use MSMQ as a transport in NServiceBus. Here's how it may look like:

  • send a command via MSMQ
  • in a command handler (re)create an aggregate which is the target of the command
  • invoke the operations
  • store the resulting events in the EventStore along with the command's message id to ensure idempotence. The aggregate itself will be responsible for knowing the commands it already processed
  • in a separate component (event processor) use EventStore persistent subscription APIs to hook to all events stream. Some of these processed events should cause sending a command. Such a command might be send via NServiceBus send-only endpoint hosted inside this event processor.
  • in that event processor you can also re-publish all events via NServiceBus and MSMQ. Such events should not be subscribed by other services (see note on autonomy below)
  • NServiceBus Sagas (process managers) should live inside your service boundary and react on commands and/or events sent or re-published by these event processors over MSMQ.

One remark regarding the service boundaries is that you have to decide what level of service autonomy suits you: * Weak, where services can directly subscribe to other service event streams. In this design events that cross service boundary are obviously allowed to carry data. * Strong, where services use higher-level events for communication and these events only carry the identity of things and no data. If you want something like this, you can use your event processors to map from ES events to these "higher level" events.