This project contains a basic implementation of the Outbox Pattern in C#.
Often when the state of a business entity changes, you want to publish an event stating that this has happened so that other microservices are in sync. To achieve this, you would do the following:
- Receive message
- Update business entity
- Publish 'EntityUpdated' event
However, if step (2) is not idempotent and only step (3) fails, we find ourselves in a scenario where the business entity has been updated an other microservices are not aware of this change.
The Outbox Pattern solves this problem by moving the event publisher into an outbox processor. The command service then updates the entity and adds a record to the outbox messages in the same transaction. The outbox processor will poll this outbox messages for any unprocessed messages, and publish them as they arrive. This is illustrated in the diagram below:
This project demo's the Outbox Pattern using NServiceBus (In Memory) and EntityFramework (SQLite). It contains 3 apps:
App | Purpose |
---|---|
OutboxPatternDemo.MedicalRecords | ASP.NET Web API that allows you to update medical records, and uses the Outbox Pattern to guarantee that update events are published at least once |
OutboxPatternDemo.Bookings | Console App that subscribes to and de-duplicates messages, and uses a saga to book follow up appointments |
OutboxPatternDemo.Monitoring | Runs the Particular Service Platform, which allows you to monitor events within the system |
All of the code is in the src
folder. It requires the dotnet 6 SDK to run.
Get your free development license from: https://particular.net/license/nservicebus?t=0&p=servicepulse
Then, copy your license.xml
file to %LocalAppData%/ParticularSoftware
. You may need to restart VS (or potentially your PC) for the license file to be picked up. This will be required NSB monitoring.
The underlying data source for outbox events uses SQL Server. Before you can run the OutboxPatternDemo.MedicalRecords/Bookings apps, you need to create a local database called OutboxPatternDemo
.
First, verify that Entity Framework is installed:
# install + update Entity Framework tool
dotnet tool install --global dotnet-ef
dotnet tool update --global dotnet-ef
Then, run the following commands from a PowerShell terminal in the src/OutboxPatternDemo.MedicalRecords
directory:
# create contexts
dotnet ef database update --context MedicalRecordContext
dotnet ef database update --context CustomOutboxContext
and the following commands from the src/OutboxPatternDemo.Bookings
directory:
# create contexts
dotnet ef database update --context DuplicateKeyContext
First, verify that Entity Framework is installed:
# install + update Entity Framework tool
dotnet tool install --global dotnet-ef
dotnet tool update --global dotnet-ef
src/OutboxPatternDemo.MedicalRecords
:
# create contexts
dotnet ef migrations add <migrationname> --context MedicalRecordContext
dotnet ef migrations add <migrationname> --context CustomOutboxContext
src/OutboxPatternDemo.Bookings
:
# create contexts
dotnet ef migrations add <migrationname> --context DuplicateKeyContext