MgMediator 1.0.0

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

MgMediator

A simple, lightweight Mediator implementation for .NET, inspired by MediatR. It supports Commands, Queries, Notifications, and Pipeline Behaviors with automatic dependency injection registration.

Installation

Register MgMediator in your Program.cs or Startup.cs:

using MgMediator;

var builder = WebApplication.CreateBuilder(args);

// Register Mediator and automatically scan for handlers and behaviors in all assemblies
builder.Services.AddMgMediator();

Core Concepts

1. Commands

Commands are used to perform actions that change state. They can return a response.

Define a Command:

public record CreateUserCommand(string Username) : ICommand<Guid>;

Define a Command Handler:

public class CreateUserCommandHandler : ICommandHandler<CreateUserCommand, Guid>
{
    public async Task<Guid> HandleAsync(CreateUserCommand command, CancellationToken cancellationToken)
    {
        // Logic to create user
        var userId = Guid.NewGuid();
        return userId;
    }
}

Send a Command:

var userId = await mediator.SendCommandAsync<CreateUserCommand, Guid>(new CreateUserCommand("johndoe"));

2. Queries

Queries are used to retrieve data without changing state.

Define a Query:

public record GetUserQuery(Guid UserId) : IQuery<UserDto>;
public record UserDto(Guid Id, string Username);

Define a Query Handler:

public class GetUserQueryHandler : IQueryHandler<GetUserQuery, UserDto>
{
    public async Task<UserDto> HandleAsync(GetUserQuery query, CancellationToken cancellationToken)
    {
        // Logic to fetch user
        return new UserDto(query.UserId, "johndoe");
    }
}

Send a Query:

var user = await mediator.SendQueryAsync<GetUserQuery, UserDto>(new GetUserQuery(userId));

3. Notifications

Notifications allow for communication between components.

Define a Notification:

public record UserCreatedNotification(Guid UserId) : INotification<bool>;

Define a Notification Handler:

public class UserCreatedNotificationHandler : INotificationHandler<UserCreatedNotification, bool>
{
    public async Task<bool> HandleAsync(UserCreatedNotification notification, CancellationToken cancellationToken)
    {
        // Logic for notification (e.g., send email)
        return true;
    }
}

Notify:

// Returns the response from the registered handler
var result = await mediator.NotifyAsync<UserCreatedNotification, bool>(new UserCreatedNotification(userId));

4. Pipeline Behaviors

Behaviors allow you to wrap command and query execution with cross-cutting concerns like logging, validation, or caching.

Define a Behavior:

public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    public async Task<TResponse> HandleAsync(TRequest request, Func<Task<TResponse>> next, CancellationToken cancellationToken)
    {
        Console.WriteLine($"Handling {typeof(TRequest).Name}");
        var response = await next();
        Console.WriteLine($"Handled {typeof(TRequest).Name}");
        return response;
    }
}

Behaviors are automatically registered and applied to both Commands and Queries.

Integration with FluentValidation

To use FluentValidation with MgMediator, you can create a validation behavior that implements IPipelineBehavior.

1. Install NuGet Packages

Add the following packages to your project:

  • FluentValidation
  • FluentValidation.DependencyInjectionExtensions

2. Create Validation Behavior

Create a class that intercepts requests and runs validators. This will be automatically registered by AddMgMediator():

using FluentValidation;
using MgMediator.Interfaces;

public class ValidationBehavior<TRequest, TResponse>(IEnumerable<IValidator<TRequest>> validators) 
    : IPipelineBehavior<TRequest, TResponse>
{
    public async Task<TResponse> HandleAsync(TRequest input, Func<Task<TResponse>> next, CancellationToken cancellationToken = default)
    {
        if (!validators.Any())
        {
            return await next();
        }

        var context = new ValidationContext<TRequest>(input);
        
        var validationResults = await Task.WhenAll(
            validators.Select(v => v.ValidateAsync(context, cancellationToken)));
        
        var failures = validationResults
            .SelectMany(r => r.Errors)
            .Where(f => f != null)
            .ToList();

        if (failures.Count != 0)
        {
            throw new ValidationException(failures);
        }

        return await next();
    }
}

3. Register Services

Register your validators in Program.cs. The AddMgMediator() call handles the behavior registration automatically.

// Register all validators from your assembly
builder.Services.AddValidatorsFromAssembly(typeof(Program).Assembly);

// Register MgMediator
builder.Services.AddMgMediator();

4. Example Usage

Define your command and a corresponding validator:

public record CreateUserCommand(string Username, string Email) : ICommand<Guid>;

public class CreateUserValidator : AbstractValidator<CreateUserCommand>
{
    public CreateUserValidator()
    {
        RuleFor(x => x.Username).NotEmpty().MaximumLength(50);
        RuleFor(x => x.Email).NotEmpty().EmailAddress();
    }
}

Features

  • Automatic Registration: AddMgMediator() scans all loaded assemblies for handlers and behaviors.
  • Pipeline Support: Add cross-cutting concerns using IPipelineBehavior.
  • Lightweight: Minimal dependencies and easy to integrate.
Product Compatible and additional computed target framework versions.
.NET 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
1.0.0 102 6/21/2026