making workflow implementation easy with cqrs
Post on 16-Apr-2017
507 Views
Preview:
TRANSCRIPT
Andrea Saltarello @andysal74
CEO @ Managed Designshttp://www.manageddesigns.it
Making workflow implementation easy with
CQRS
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
A workflow consists of an orchestrated and repeatable pattern of business activity enabled by the systematic organization of resources into processes that transform materials, provide services, or process information.[1]
It can be depicted as a sequence of operations, declared as work of a person or group,[2] an organization of staff, or one or more simple or complex mechanisms.
[Wikipedia]
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
A simple workflow: Invoicing
Issue
Payment
Ship
NotifyExpires IsPaid CollectNo
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
A simple workflow: Invoicing
Either a user or a scheduler fires code such as:
public void NotifyCustomersAboutPertainingExpiredInvoices()
{
var expiredInvoices = from i in db.OutgoingInvoices
where SomeClausesPointingToStillUnpaidExpiredInvoicesselect i;
foreach(var invoice in expiredInvoices)
{
NotifyExpiredInvoiceToCustomer(invoice);
}
}
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
Enter CQRS
Presentation layer
Application layer
Infrastructure layer
Domain Model
Domain layer
Presentation layer
Infrastructure layer
CQRS
Queries
Data access
Commands
Application+
Domain
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
Why CQRS?
We faced a lot of complexity in modelingWe thought it was inherent domain complexityLong story short: a single model caring about all aspects of the domain is hard. Enter CQS
Command/Query Separation (cit. Bertrand Meyer – 1980s)
Query> Returns data> Doesn’t alter state
Command> Alter state > Doesn’t return data
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
CQRS in action
As a business unit manager, I want to notify customers about expired invoices
Database.OutgoingInvoices..PerBusinessUnit(businessUnitId).ExpiredOnly().Select(i => new {InvoiceNumber = i.Number, CustomerId =
i.Customer.Id}).AsParallel().ForAll(i => NotifyCustomer(i.InvoiceNumber, i.CustomerId));
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
The result
Pros:• Easy to read• Close to Ubiquitous Language
Cons:• Synchronous (lower scalability)• Either a scheduling engine or human interaction is
required
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
Commands: a different strategy
1. Application sends a command to the system2. Commands are dispatched to workflow managers
(a.k.a. Sagas) which will execute them and then state success/failure accordingly
3. Responses are notified to interested subscribers (a.k.a. handlers) such as Denormalizers, which will (eventually) update the read model’s database
Note: command/responses dispatch will be managed by a Mediator
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
CQRS in action, part 2
As a business unit manager, I want to notify customers about expired invoicesDatabase
.OutgoingInvoices.
.PerBusinessUnit(businessUnitId)
.ExpiredOnly()
.Select(i => new {InvoiceNumber = i.Number, CustomerId = i.Customer.Id})
.AsParallel()
.ForAll(i => mediator.Send(new NotifyPaymentDueCommand(i.InvoiceNumber, i.CustomerId)));
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
The result, part 2
Pros:• Easy to read• Close to Ubiquitous Language• Asynchronous
Cons:• Either a scheduling engine or human interaction is
required
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
Queues or buses? That is the question (semi cit. )
Although both categories are viable options and support common features (e.g.: message durability), a bus is generally preferable due to advanced capabilities (e.g.: message scheduling)
Mediator, who art thou?
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
Sagas 1-2-3
In a messaging system, a saga orchestrate a set of messages. The main benefit of using a saga is that it allows us to manage the interaction in a stateful manner (easy to think and reason about) while actually working in a distributed and asynchronous environment.
[Ayende]
Though Saga are not proper workflow/process manager, they are effective at pretending to be
Sagas in action
Introduction to ServiceInsight for NServiceBusMaking workflow implementation easy with CQRS
More resources: •“Microsoft .NET: Architecting Applications for the Enterprise” by Andrea Saltarello and Dino Esposito, Microsoft Press (2014)•Merp (http://naa4e.codeplex.com)
Links
Thank you
top related