Plug your existing domain models into NServiceBus Sagas
Tags: nservicebus, ddd, soa, microservices
Published: 2020-07-06 15:13:17

“An NServiceBus saga is an Aggregate root.” *Udi Dahan*

“An aggregate can be seen as a state machine/workflow so a very good solution when using NServiceBus is to use sagas to implement aggregates.” *Mauro Servienti*

Mauro Servienti also states that, if needed, domain events can be published by NServiceBus. There is no need to reinvent the wheel.

This article will explain how to plug an “existing” aggregate into an NServiceBus saga.

But why should one ever do that? Why not use sagas as aggregates instead of adding another layer of indirection?

Because legacies are everywhere. Maybe you aren’t using NServiceBus already and now you want to adopt it. For example, you may have “deferred” some infrastructural decisions while designing your system, and now you’ve come up with adopting NServiceBus to make your system more scalable, or eliminate the maintenance of all the unnecessary home-made implementations, and focus on solving your core business problems instead. Let’s keep it short.

Imagine the following user aggregate:

{% gist https://gist.github.com/Mohsen-Bazmi/b8ea60f16135da75d4d5b50b051102e3 %}

Now we want to plug it into the following NServiceBus Saga:

{% gist https://gist.github.com/Mohsen-Bazmi/101adbdc846a2aae1e7ec5754f4c8be4 %}

So we don’t have to implement the repository to persist the user aggregate. The saga takes care of that for us.

Another benefit is that NServiceBus publishes the domain events which keeps us from maintaining all the unnecessary infrastructure to store the events, pick them up, put them into the queue, notify the listeners, and preserve the transaction consistency.

We need to focus on our core business problems instead of reinventing the wheel.

{% gist https://gist.github.com/Mohsen-Bazmi/fd5a26cf30698d2a1a915e35f4dfce7b %}  


But what about the order of the events? Does NServiceBus preserve the order of the events? Well, as far as I know, NServiceBus does not have that option. The order of messages matter in some scenarios. Preserving the order is not the responsibility of the messaging infrastructure. We can easily attach a version to each event before publishing them, which can be a subject for another post. Here is a modified version of the previous extension method to show the idea.  


{% gist https://gist.github.com/Mohsen-Bazmi/f4e26da581d1c1fd97ccac620de72620 %}

You got it. But it’s tricky to plug your domain events into sagas. The complete runnable sample project and the additional classes that help the NServiceBus SagaData class wrap the aggregate can be found in [this GitHub repository](https://github.com/Mohsen-Bazmi/NSBPlugAggregatesToSagas). I 

Special thanks to Mauro Servienti, solution architect from Particular Software for answering my questions, and for helping me with editing this article.

**Summary**
You can use sagas as your aggregate roots and keep things simpler, but in legacy scenarios, it’s usually not worth it.
You may have “deferred” some infrastructural decisions and now you’ve decided to adopt NServicebus to make your system more scalable.
An NServiceBus Saga can wrap DDD style aggregates so that you can focus on your core business problems. 

*Focus on your core business problems rather than implementing Infrastructure.*

Thank you for reading.