Skip to content

stevsharp/OutboxPattern

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧩 Domain Events & Outbox Pattern (.NET 9)

This challenge demonstrates how to implement Domain Events and the Outbox Pattern using Entity Framework Core with SQLite and Background Services in .NET 9.

It ensures domain events are saved atomically with aggregate changes and then published reliably from an Outbox table by a background dispatcher.


🚀 Tech Stack

Component Purpose
.NET 9 Framework
EF Core + SQLite Persistence layer
SaveChangesInterceptor Captures domain events before save
BackgroundService Dispatches outbox messages
System.Text.Json Serializes domain events
Swashbuckle.AspNetCore Swagger UI for testing endpoints

🏗️ Architecture Overview

┌────────────────────────────────────────┐
│           API  +  EF Core              │
│ ───────────────────────────────────── │
│  Order Aggregate raises Domain Event   │
│  → EF Interceptor saves Outbox row     │
│  → Transaction commits atomically      │
└──────────────┬─────────────────────────┘
               │
               ▼
       📨 Outbox Dispatcher (Hosted Service)
           ├─ Reads unprocessed messages
           ├─ Publishes events (console bus)
           └─ Marks as processed

📂 Project Structure

Challenge05_Outbox/
│
├── Program.cs
│
├── Domain/
│   ├── DomainEvent.cs
│   ├── IHasDomainEvents.cs
│   ├── Order.cs
│   └── OrderPlacedDomainEvent.cs
│
└── Infrastructure/
    ├── AppDbContext.cs
    ├── OutboxMessage.cs
    ├── OutboxDispatcher.cs
    ├── OutboxSaveChangesInterceptor.cs
    ├── IEventSerializer.cs
    └── SystemTextJsonEventSerializer.cs

⚙️ Setup Instructions

1️⃣ Clone the Repository

git clone https://github.com/YOUR_USERNAME/Challenge05_Outbox.git
cd Challenge05_Outbox

2️⃣ Install Dependencies

dotnet restore
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Swashbuckle.AspNetCore

3️⃣ Create and Apply Migration

dotnet tool install --global dotnet-ef
dotnet ef migrations add Init
dotnet ef database update

This will create a local SQLite file: challenge05.db


🧩 Run the Project

dotnet run

Open:


🧪 Try It Out

➕ Create an Order

curl -X POST "http://localhost:5000/orders?total=49.99"

📬 Check Outbox Messages

curl "http://localhost:5000/outbox"

Console output example:

[BUS] ✅ OrderPlaced published => OrderId=6fdc..., Total=49.99

💾 Database Schema (Simplified)

Table Purpose
Orders Domain aggregate
OutboxMessages Stores serialized domain events

SQLite DDL:

CREATE TABLE "OutboxMessages" (
    "Id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "OccurredOnUtc" TEXT NOT NULL,
    "Type" TEXT NOT NULL,
    "Payload" TEXT NOT NULL,
    "ProcessedOnUtc" TEXT NULL,
    "Error" TEXT NULL
);
CREATE INDEX "IX_OutboxMessages_ProcessedOnUtc"
ON "OutboxMessages" ("ProcessedOnUtc");

🔁 Event Flow

  1. Aggregate raises event

    AddEvent(new OrderPlacedDomainEvent(Id, Total));
  2. Interceptor captures it during SaveChangesAsync and writes an OutboxMessage in the same transaction.

  3. Background service polls for unprocessed messages and “publishes” them (here, simulated with console output).

  4. Marks processedProcessedOnUtc is updated.


🧠 Key Files

  • OutboxSaveChangesInterceptor.cs → Captures domain events pre-save
  • OutboxDispatcher.cs → Processes messages asynchronously
  • SystemTextJsonEventSerializer.cs → Serializes/deserializes events
  • AppDbContext.cs → Entity mappings + EF setup

📦 NuGet Packages

Package Purpose
Microsoft.EntityFrameworkCore.Sqlite SQLite provider
Microsoft.EntityFrameworkCore.Design CLI migrations
Swashbuckle.AspNetCore Swagger documentation
Microsoft.Extensions.Hosting Background services
Microsoft.Extensions.Logging.Console Logging

🧱 Future Improvements

  • Add retry & backoff policy in dispatcher
  • Use a real message bus (e.g., RabbitMQ or Kafka)
  • Introduce event versioning and handlers registry
  • Add unit tests with InMemory EF provider

📜 License

This project is licensed under the MIT License. Feel free to use / modify / share.


👤 Author

Spyros Ponaris 💼 LinkedIn


About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages