SwartBerg.Mediator 2.0.10

dotnet add package SwartBerg.Mediator --version 2.0.10
                    
NuGet\Install-Package SwartBerg.Mediator -Version 2.0.10
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SwartBerg.Mediator" Version="2.0.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SwartBerg.Mediator" Version="2.0.10" />
                    
Directory.Packages.props
<PackageReference Include="SwartBerg.Mediator" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SwartBerg.Mediator --version 2.0.10
                    
#r "nuget: SwartBerg.Mediator, 2.0.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SwartBerg.Mediator@2.0.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SwartBerg.Mediator&version=2.0.10
                    
Install as a Cake Addin
#tool nuget:?package=SwartBerg.Mediator&version=2.0.10
                    
Install as a Cake Tool

SwartBerg.Mediator

Build Status Release NuGet Version NuGet Downloads License: MIT

A mediator implementation for with background processing and notification persistence.

Inspired by MediatR, this library was created as a free alternative with similar patterns but includes built-in persistence and background processing.

The name "SwartBerg" means "Black Mountain" in Afrikaans, it is a combination of my surname and my wife's maiden name. If you like to thank me for the library buy me a coffee. Link is at the bottom of this readme.

Features

  • High Performance: Precompiled generic delegates (no runtime expression compilation)
  • Background Processing: Non-blocking notification dispatch with worker pool
  • Pipeline Behaviors: Plug-in cross-cutting concerns
  • Configurable Persistence: Pluggable store & serializer
  • Retry Logic: Exponential backoff with precomputed delays
  • Modern Async Patterns: Optional global ConfigureAwait(false)
  • Lightweight: Low allocations, minimal deps

Requirements

  • .NET 8.0 or later
  • Works with:
    • .NET 8+ applications
    • .NET MAUI applications
    • Blazor applications
    • ASP.NET 8+ Core applications
    • Console applications
    • WPF applications
    • WinForms applications

Installation

Package Manager Console

Install-Package SwartBerg.Mediator

.NET CLI

dotnet add package SwartBerg.Mediator

PackageReference

<PackageReference Include="SwartBerg.Mediator" Version="2.0.3" />

Quick Start

1. Define your requests and handlers

public class GetUserQuery : IRequest<User>
{
    public int UserId { get; set; }
}

public class GetUserHandler : IRequestHandler<GetUserQuery, User>
{
    public Task<User> Handle(GetUserQuery request, CancellationToken cancellationToken)
    {
        return Task.FromResult(new User { Id = request.UserId, Name = "John Doe" });
    }
}

public class CreateUserCommand : IRequest
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class CreateUserHandler : IRequestHandler<CreateUserCommand>
{
    public Task Handle(CreateUserCommand request, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

public class UserCreatedNotification : INotification
{
    public int UserId { get; set; }
    public string Name { get; set; }
}

public class SendWelcomeEmailHandler : INotificationHandler<UserCreatedNotification>
{
    public Task Handle(UserCreatedNotification notification, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

2. Register services

builder.Services.AddMediator(typeof(Program).Assembly);

3. Use the mediator

public class UserController : ControllerBase
{
    private readonly IMediator _mediator;

    public UserController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpGet("{id}")]
    public async Task<User> GetUser(int id)
    {
        return await _mediator.Send(new GetUserQuery { UserId = id });
    }

    [HttpPost]
    public async Task CreateUser(CreateUserCommand command)
    {
        await _mediator.Send(command);
        await _mediator.Publish(new UserCreatedNotification { UserId = 1, Name = command.Name });
    }
}

Advanced Configuration

Pipeline Behaviors

public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        ValidateRequest(request);
        return await next();
    }
}

services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));

Custom Persistence

services.AddSingleton<INotificationPersistence, RedisNotificationPersistence>();
services.AddSingleton<INotificationPersistence, SqlServerNotificationPersistence>();
services.AddMediator(options => options.EnablePersistence = false, typeof(Program).Assembly);

Configuration Options

services.AddMediator(options =>
{
    options.NotificationWorkerCount = 4;
    options.EnablePersistence = true;
    options.ProcessingInterval = TimeSpan.FromSeconds(30);
    options.ProcessingBatchSize = 50;
    options.MaxRetryAttempts = 3;
    options.InitialRetryDelay = TimeSpan.FromMinutes(2);
    options.RetryDelayMultiplier = 2.0;
    options.CleanupRetentionPeriod = TimeSpan.FromHours(24);
    options.CleanupInterval = TimeSpan.FromHours(1);
    // options.UseConfigureAwaitGlobally = false; // only if you need sync ctx
}, typeof(Program).Assembly);

Architecture

Channel-first with optional persistence:

  1. In-memory channel dispatch
  2. Optional persistence backup
  3. Periodic recovery loop
  4. Periodic cleanup loop
Publish() → Channel → Background Workers
        ↘
         Persist() → Storage
              ↘
         Recovery → Channel

Performance improvements in recent updates:

- Cached concrete handler factories for faster scoped resolution when dispatching notifications.
- Notification handler type caching to avoid holding root-scoped instances and reduce allocations.
- Delayed serialization during Publish to avoid unnecessary serialization when persistence is disabled or fails.

## Testing

```bash
dotnet test

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Add changes + tests
  4. Run benchmarks
  5. Commit: git commit -m 'Add amazing feature'
  6. Push: git push origin feature/amazing-feature
  7. Open PR

License

MIT License - see LICENSE.

Support

Open issues for bugs or features. Provide clear reproduction steps.

Appreciation (Optional)

Free forever. If it helps you and you want to buy a coffee:

Buy Me A Coffee

**Always free. No premium features, no paid support.**Always free.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.10 132 2/19/2026
2.0.9 90 2/18/2026
2.0.8 141 2/12/2026
2.0.7 115 2/7/2026
2.0.6 128 2/1/2026
2.0.5 98 2/1/2026
2.0.4 99 1/31/2026
2.0.3 100 1/28/2026
2.0.2 130 1/23/2026
2.0.1 99 1/22/2026
2.0.0 159 1/9/2026
1.0.5 245 11/24/2025
1.0.4 426 11/20/2025
1.0.3 420 11/19/2025
1.0.2 419 11/19/2025
1.0.1 186 10/31/2025
1.0.0 236 9/20/2025
0.1.4-ci0010 215 9/20/2025

Version 2.0.0: Added support for .NET 10. High-performance mediator with compiled expressions, background notifications, pipeline behaviors, file-based persistence with retry logic, and built-in ConfigureAwait(false) for automatic deadlock prevention. Safe by default for all application types. Supports .NET 9 and .NET 10.