Skip to content

dementcore/Mediate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

114 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Mediate

Mediate

Lightweight in-process mediator for .NET 10 β€” queries, events, middleware & pluggable dispatch strategies.

NuGet Documentation Status


✨ What is Mediate?

Mediate is a simple, zero-dependency in-process messaging library for .NET 10 based on the Mediator pattern. It helps you build loosely coupled applications by routing queries (request/response) and events (fan-out notifications) through a central hub, with full middleware pipeline support and swappable dispatch strategies.

Designed to be small, explicit, and easy to extend β€” no magic, no hidden conventions.


πŸ“¦ Packages

Package Description NuGet
Mediate Core library β€” mediator, queries, events, middleware NuGet
Mediate.BackgroundEventDispatch ASP.NET Core extension β€” fire-and-forget background event dispatch NuGet

πŸš€ Quick Start

1. Install

dotnet add package Mediate

2. Register

// Program.cs
builder.Services.AddMediate();

// Register your handlers and middlewares from an assembly
builder.Services.AddMediateClassesFromAssembly(typeof(Program).Assembly);

// Pick a dispatch strategy (default: sequential)
builder.Services.AddMediateSequentialEventDispatchStrategy();

3. Define a query

public record GetUserQuery(int Id) : IQuery<UserDto>;

public class GetUserHandler : IQueryHandler<GetUserQuery, UserDto>
{
    public Task<UserDto> Handle(GetUserQuery query, CancellationToken cancellationToken)
        => Task.FromResult(new UserDto(query.Id, "Alice"));
}

4. Define an event

public record UserCreatedEvent(int UserId) : IEvent;

public class SendWelcomeEmailHandler : IEventHandler<UserCreatedEvent>
{
    public Task Handle(UserCreatedEvent @event, CancellationToken cancellationToken)
    {
        // send email...
        return Task.CompletedTask;
    }
}

5. Use the mediator

public class UserService(IMediator mediator)
{
    public async Task<UserDto> GetUser(int id)
        => await mediator.Send(new GetUserQuery(id));

    public async Task CreateUser(int id)
    {
        // ... create user ...
        await mediator.Dispatch(new UserCreatedEvent(id));
    }
}

🧩 Features

πŸ” Query / Handler (Request-Response)

Send a query and get exactly one response. Each query type maps to exactly one handler.

TResult result = await mediator.Send(new MyQuery(...));

πŸ“’ Event / Handler (Fan-out)

Dispatch an event to zero or more handlers simultaneously.

await mediator.Dispatch(new MyEvent(...));

πŸ”— Middleware Pipelines

Wrap query and event handling with middleware β€” great for logging, validation, tracing, and cross-cutting concerns. Middleware runs in registration order.

Query middleware:

public class LoggingMiddleware<TQuery, TResult> : IQueryMiddleware<TQuery, TResult>
    where TQuery : IQuery<TResult>
{
    public async Task<TResult> Execute(
        TQuery query,
        NextMiddlewareDelegate<TResult> next,
        CancellationToken cancellationToken)
    {
        Console.WriteLine($"Handling {typeof(TQuery).Name}");
        TResult result = await next();
        Console.WriteLine($"Done handling {typeof(TQuery).Name}");
        return result;
    }
}

Event middleware:

public class LoggingEventMiddleware<TEvent> : IEventMiddleware<TEvent>
    where TEvent : IEvent
{
    public async Task Execute(
        TEvent @event,
        NextMiddlewareDelegate next,
        CancellationToken cancellationToken)
    {
        Console.WriteLine($"Dispatching {@event.GetType().Name}");
        await next();
    }
}

⚑ Pluggable Dispatch Strategies

Control how event handlers are invoked by swapping the dispatch strategy:

Strategy Behavior
SequentialEventDispatchStrategy Handlers run one after another; collects all exceptions into AggregateException
ParallelEventDispatchStrategy Handlers run concurrently via Parallel.ForEachAsync
EventQueueDispatchStrategy Fire-and-forget background queue (requires Mediate.BackgroundEventDispatch)
// Sequential (default)
services.AddMediateSequentialEventDispatchStrategy();

// Parallel
services.AddMediateParallelEventDispatchStrategy();

// Custom
services.AddMediateCustomDispatchStrategy<MyStrategy>(ServiceLifetime.Scoped);

πŸ”§ Fluent Builder

For fine-grained control over provider registration:

services.AddMediateCore()
    .AddServiceProviderHandlerProvider()
    .AddServiceProviderMiddlewareProvider();

You can plug in completely custom handler or middleware providers:

services.AddMediateCore()
    .AddCustomHandlerProvider<MyHandlerProvider>()
    .AddCustomMiddlewareProvider<MyMiddlewareProvider>();

πŸ” Assembly Scanning

Auto-register all handlers and middlewares from an assembly in one call:

services.AddMediateClassesFromAssembly(typeof(Program).Assembly);

🌐 Background Event Dispatch

The Mediate.BackgroundEventDispatch package adds a fire-and-forget dispatch strategy backed by an in-memory queue and an ASP.NET Core BackgroundService.

dotnet add package Mediate.BackgroundEventDispatch
builder.Services.AddMediate();
builder.Services.AddMediateEventQueueDispatchStrategy();

Events dispatched with mediator.Dispatch(...) are enqueued immediately and processed asynchronously in the background. The queue has a bounded capacity of 10 items with semaphore-based backpressure.

Custom exception handling:

builder.Services.AddMediateEventQueueDispatchStrategyCore()
    .AddCustomExceptionHandler<MyExceptionHandler>();

πŸ“– Documentation

Full documentation, guides, and API reference at:

mediate.readthedocs.io


πŸ—οΈ Architecture Overview

IMediator
β”œβ”€β”€ Send<TResult>(IQuery<TResult>)       β†’ one handler + query middleware pipeline
└── Dispatch<TEvent>(TEvent)             β†’ N handlers + event middleware pipeline
                                              └── via IEventDispatchStrategy

Providers resolve handlers and middlewares from the DI container:

  • IQueryHandlerProvider / IEventHandlerProvider
  • IQueryMiddlewareProvider / IEventMiddlewareProvider

Default implementations (ServiceProviderHandlerProvider, ServiceProviderMiddlewareProvider) delegate directly to IServiceProvider.


🀝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to open an issue or submit a pull request.


πŸ“„ License

MIT Β© DementCore

About

Mediate is another simple and little in-process messaging and event dispatching system based in mediator pattern.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages