Table of Contents

Messaging Patterns

This section covers messaging and event-driven patterns in PatternKit, with a focus on the Mediator pattern.

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.

Learn More →

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

The Source-Generated Mediator complements other PatternKit patterns:

  • 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)