TheMediator 1.0.3

dotnet add package TheMediator --version 1.0.3
                    
NuGet\Install-Package TheMediator -Version 1.0.3
                    
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="TheMediator" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TheMediator" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="TheMediator" />
                    
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 TheMediator --version 1.0.3
                    
#r "nuget: TheMediator, 1.0.3"
                    
#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 TheMediator@1.0.3
                    
#: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=TheMediator&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=TheMediator&version=1.0.3
                    
Install as a Cake Tool

TheMediator

<img src="./TheMediator.Core/icon.png" alt="drawing" style="width:200px;"/>

.NET

NuGet

TheMediator é uma implementação de alto desempenho do padrão Mediator para .NET, com suporte a Filters e Notifications. É leve, extensível e rápido, ideal para desacoplar componentes em sistemas.

Esse projeto faz parte da saga "Reinventando a Roda: Criando seu próprio MediatR", onde eu crio uma implementação própria.

Foram 3 posts no total:

Instalação

Você pode instalar o pacote via NuGet usando o seguinte comando:

dotnet add package TheMediator --version 1.0.1

Feito isso, você pode registrar o Mediator no seu projeto:

builder.Services.AddTheMediator(configuration =>
{
    configuration.AddServicesFromAssemblies(typeof(Program).Assembly);
    
    configuration.Filters.Add<LoggingFilter>();
    
    configuration.Notifiers.Configurations.DeliveryMode = NotificationDeliveryMode.FireAndForget;
}); 

Funcionalidades

Handlers

Os Handlers são responsáveis por processar as requisições.

Eles implementam a interface IRequestHandler<TRequest, TResponse>, onde TRequest é o tipo da requisição e TResponse é o tipo da resposta.

TResponse não é obrigatório, e o TRequest pode ser qualquer tipo, incluindo string, int, Guid, etc.

É possível ter mais de um Handler para o mesmo tipo de requisição (TRequest) contanto que o TResponse seja diferente.

Os Handlers são registrados automaticamente pelo método AddServicesFromAssemblies no AddTheMediator.

Exemplo de uso:

public record ProductRequest(string Name, decimal Price);

public record ProductResponse(Guid Id, string Name, decimal Price);

public class CreateProductRequestHandler(IProductsRepository repository)
    : IRequestHandler<ProductRequest, ProductResponse>
{
    public async Task<ProductResponse> HandleAsync(ProductRequest request, CancellationToken cancellationToken)
    {
        var created = await repository.Create(request, cancellationToken);
        return created;
    }
}

public class SearchProductRequestHandler(IProductsRepository repository)
    : IRequestHandler<string, IReadOnlyCollection<ProductResponse>?>
{
    public Task<IReadOnlyCollection<ProductResponse>?> HandleAsync(
        string? query,
        CancellationToken cancellationToken)
    {
        return repository.Search(query, cancellationToken);
    }
}

// Exemplo de uso

app.MapPost("/products",
        async (
            [FromServices] ISender sender,
            [FromBody] ProductRequest request,
            CancellationToken cancellationToken) =>
        {
            var response = await sender.SendAsync<ProductRequest, ProductResponse?>(request, cancellationToken);
            return response is null
                ? Results.BadRequest("Cannot create product")
                : Results.Created($"/products/{response.Id}", response);
        })
    .WithName("Products.Post.ProductRequest");

Filters

Os Filters permitem adicionar lógica antes ou depois da execução de um handler, como validações, logging ou manipulação de exceções.

Exemplo de uso:

public class LoggerRequestFilter(ILogger<LoggerRequestFilter> logger)
    : IRequestFilter
{
    public Task<TResponse> FilterAsync<TRequest, TResponse>(TRequest request, Func<Task<TResponse>> next,
        CancellationToken cancellationToken)
        where TRequest : notnull
    {
        logger.LogInformation("{Type} execution started: {Time}", request.GetType().Name, DateTime.Now);
        var response = next();
        logger.LogInformation("{Type} execution finished: {Time}", request.GetType().Name, DateTime.Now);
        return response;
    }
}

Os Filters devem ser registrados manualmente no AddTheMediator e a ordem de execução é a ordem em que foram registrados.

Notifications

As Notifications permitem enviar mensagens para múltiplos handlers de forma assíncrona (quando o delivery mode é FireAndForget) ou síncrona (quando o delivery mode é WaitForAll).

O DeliveryMode padrão é FireAndForget, e ele pode ser configurado no AddTheMediator.

As Notifications são registrados automaticamente pelo método AddServicesFromAssemblies no AddTheMediator.

Exemplo de uso:

public class LogInfoProductCreatedNotification(ILogger<LogInfoProductCreatedNotification> logger)
    : INotificationHandler<ProductResponse>
{
    public async Task HandleAsync(ProductResponse notification, CancellationToken cancellationToken)
    {
        logger.LogInformation("{Class} Product {ProductName} created", nameof(CreateProductNotification),
            notification.Name);
    }
}

public class SendEmailProductCreatedNotification(ILogger<SendEmailProductCreatedNotification> logger, IEmailService emailService)
    : INotificationHandler<ProductResponse>
{
    public async Task HandleAsync(ProductResponse notification, CancellationToken cancellationToken)
    {
        await emailService.SendAsync($"Product {notification.Name} created...", notification.Dump(), cancellationToken);
    }
}

// Exemplo de uso

public class CreateProductRequestHandler(IPublisher publisher, IProductsRepository repository)
    : IRequestHandler<ProductRequest, ProductResponse>
{
    public async Task<ProductResponse> HandleAsync(ProductRequest request, CancellationToken cancellationToken)
    {
        var created = await repository.Create(request, cancellationToken);
        await publisher.PublishAsync(created, cancellationToken);
        return created;
    }
}

Logging

O TheMediator utiliza o ILogger para registrar informações sobre as requisições e respostas via método Trace.

Por default, essa opção vem desabilitada.

Para mudar essa configuração é necessário mudar o level do logger no appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "TheMediator.Core": "Trace"
    }
  }
}
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 was computed.  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 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
1.0.3 57 9/20/2025
1.0.2 62 9/20/2025
1.0.1 102 5/2/2025
1.0.0 154 4/30/2025