DEV Community

Cover image for Plug your existing domain models into NServiceBus Sagas
Mohsen Bazmi
Mohsen Bazmi

Posted on • Updated on

Plug your existing domain models into NServiceBus Sagas

“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:

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

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.

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.

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. 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.

Top comments (2)

Collapse
 
bubachelidze1 profile image
Bitchiko Tchelidze

How can we send synchronous requests to aggregate roots modeled with saga ? Say we want to support some of the async commands (received from message broker) as well as some from sync, receive from http, which requires immediate feedback. In the http request handler, how can you we "wake up" saga and invoke it's method ?

Collapse
 
mohsenbazmi profile image
Mohsen Bazmi

I'm not sure if the NServiceBus sagas have that feature. I'd rather not to handle sync commands by sagas.