Messaging Patterns
This section covers messaging and event-driven patterns in PatternKit.
Message Envelope and Context
Message<TPayload>, MessageHeaders, and MessageContext provide shared in-process metadata for enterprise integration patterns. They carry correlation IDs, causation IDs, idempotency keys, content types, reply addresses, timestamps, cancellation, and execution-scoped items without pretending to be a broker or durable queue.
Enterprise Message Routing
Content router, recipient list, splitter, and aggregator primitives model common Enterprise Integration Patterns for deterministic in-process workflows.
Routing Slip
Runtime and source-generated routing slip factories execute named message itineraries in order and record progress in message headers.
Saga / Process Manager
Runtime and source-generated process managers coordinate typed message transitions over explicit saga state.
Mailbox
Bounded or unbounded in-process inboxes serialize async message handling through a single consumer, with explicit backpressure, error, lifecycle, and diagnostics policies.
Event-Driven Consumer
Push-based consumers handle messages when a broker callback, background service, webhook, in-memory bus, or application event source delivers them.
Durable Subscriber
Durable subscribers catch up from a message store and checkpoint the last successfully handled sequence per subscriber.
Message Bus
Typed message buses publish messages to named topic subscribers backed by PatternKit message channels, with fluent and source-generated topology paths.
Channel Adapter
Channel adapters translate external transport DTOs into PatternKit message channels and translate outbound channel messages back to the transport shape.
Channel Purger
Channel purgers remove stale or operationally obsolete messages from PatternKit message channels with optional predicates and audit hooks.
Messaging Gateway
Messaging gateways expose typed request/response methods while hiding message envelope and channel plumbing from application services.
Service Activator
Service activators invoke application service operations from typed messages while preserving message context and response envelopes.
Event-Carried State Transfer
Event-carried state transfer publishes enough state in an event for subscribers to update local read models without calling back into the source service.
Event Notification
Event notification publishes compact event signals with keys, correlation IDs, and metadata when subscribers do not need a full state payload.
Idempotent Receiver, Inbox, and Outbox
Idempotency and handoff helpers compose message handlers with pluggable stores, inbox boundaries, and outbox records without claiming broker durability or exactly-once delivery.
Enterprise Integration Source Generators
Generated content routers, routing slips, and sagas remove repetitive factory registration while preserving explicit opt-in and compile-time diagnostics.
Mediator (Source Generated)
A zero-dependency, source-generated Mediator pattern implementation for commands, notifications, and streams.
The Mediator pattern reduces coupling between components by centralizing communication through a mediator object. This source-generated variant provides compile-time code generation with zero runtime dependencies on PatternKit.
Quick Start
using PatternKit.Generators.Messaging;
// Mark assembly for generation
[assembly: GenerateDispatcher(
Namespace = "MyApp.Messaging",
Name = "AppDispatcher")]
// Define messages
public record CreateUser(string Username, string Email);
public record UserCreated(int UserId, string Username);
// Build mediator
var dispatcher = AppDispatcher.Create()
.Command<CreateUser, UserCreated>((req, ct) =>
new ValueTask<UserCreated>(new UserCreated(1, req.Username)))
.Build();
// Use mediator
var result = await dispatcher.Send<CreateUser, UserCreated>(
new CreateUser("alice", "alice@example.com"),
cancellationToken);
Key Features
- ✅ Zero runtime dependency on PatternKit
- ✅ AOT-friendly - no reflection
- ✅ Async-first - ValueTask & IAsyncEnumerable
- ✅ Commands - request → response
- ✅ Notifications - fan-out to multiple handlers
- ✅ Streams - async enumerable results
- ✅ Pipelines - pre/post hooks for cross-cutting concerns
- ✅ Fluent API - easy to compose
Documentation
- Full Documentation
src/PatternKit.Examples/Messaging/DispatcherExample.cssrc/PatternKit.Examples/MediatorComprehensiveDemo/ComprehensiveDemo.cs- DI integration, CQRS, behaviors, real-world domain
Related Patterns
The Source-Generated Mediator complements other PatternKit patterns:
- Message Envelope and Context - Shared metadata for routers, routing slips, sagas, mailboxes, and idempotent receivers
- Enterprise Message Routing - Content-based router, recipient list, splitter, and aggregator primitives
- Routing Slip - Ordered message itineraries with fluent runtime and source-generated factories
- Saga / Process Manager - Typed message transitions over explicit long-running process state
- Mailbox - Serialized in-process inbox with bounded backpressure and shutdown behavior
- Idempotent Receiver, Inbox, and Outbox - Pluggable idempotency and handoff helpers for at-least-once processing
- Enterprise Integration Source Generators - Generated content-router, routing-slip, and saga factories with diagnostics
- Runtime Mediator - Pre-built mediator with PatternKit runtime (use for application code)
- Observer - For reactive event handling and pub/sub
- Command - For encapsulating requests as objects
When to Use
Use the source-generated Mediator when you need:
- ✅ Decoupled message handling in your application
- ✅ Compile-time verification of message flows
- ✅ Zero runtime dependencies (for libraries/NuGet packages)
- ✅ AOT deployment scenarios
- ✅ High-performance message routing without reflection
When Not to Use
Consider alternatives when:
- ❌ You need distributed messaging (use message broker instead)
- ❌ You need dynamic handler discovery at runtime
- ❌ Your handlers come from plugins/dynamic assemblies
- ❌ You need complex routing logic (use message broker)
Invalid Message Channel
InvalidMessageChannel<TPayload> routes messages that fail validation to a dedicated invalid-message channel with reason metadata and original headers preserved.