CleanMediator 1.0.1

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

CleanMediator

NuGet License: MIT

CleanMediator is a lightweight mediator and pipeline behavior library tailored for Clean Architecture projects. It provides structured request/response handling with optional middleware-style pipeline behaviors for pre- and post-processing logic such as logging, validation, caching, etc.


โœจ Features

  • Minimal setup, zero external dependencies.
  • Supports both commands (IRequest) and queries (IRequest<T>)
  • Pipeline behaviors for clean cross-cutting concerns
  • Automatic handler and behavior discovery
  • Built-in dependency injection support
  • Fully unit-testable
  • .NET 8+ compatible

๐Ÿ“ฆ Installation

Install via NuGet:

dotnet add package CleanMediator

๐Ÿš€ Getting Started

1. Register CleanMediator

builder.Services.AddCleanMediator();

This will automatically register:

  • All IRequestHandler<TRequest> and IRequestHandler<TRequest, TResponse> implementations
  • All IPipelineBehavior<TRequest> and IPipelineBehavior<TRequest, TResponse> behaviors

2. Create a Request (Query)

public class GetUserByIdQuery : IRequest<UserResponse>
{
    public int Id { get; set; }
}

3. Create a Handler

public class GetUserByIdHandler : IRequestHandler<GetUserByIdQuery, UserResponse>
{
    public Task<UserResponse> HandleAsync(GetUserByIdQuery request, CancellationToken cancellationToken)
    {
        return Task.FromResult(new UserResponse
        {
            Id = request.Id,
            Name = "Jane Doe"
        });
    }
}

4. Dispatch from Code (Controller)

[Route("api/[controller]")]
    [ApiController]
    public class UsersController(IRequestDispatcher dispatcher) : ControllerBase
    {
        private readonly IRequestDispatcher _dispatcher = dispatcher;

        [HttpGet("{id}")]
        public async Task<IActionResult> GetUserAsync(int id)
        {
            var result = await _dispatcher.SendAsync(new GetUserByIdQuery{ Id = id });
            return Ok(result);
        }
    }

๐Ÿ” Commands (No Response)

public class DeactivateUserCommand : IRequest
{
    public int UserId { get; set; }
}

public class DeactivateUserHandler : IRequestHandler<DeactivateUserCommand>
{
    public Task HandleAsync(DeactivateUserCommand request, CancellationToken cancellationToken)
    {
        Console.WriteLine($"User {request.UserId} deactivated");
        return Task.CompletedTask;
    }
}

[HttpPut("{id}")]
public async Task<IActionResult> DeactivateUserAsync(int id)
{
    await _dispatcher.SendAsync(new DeactivateUserCommand { UserId = id });
    return Ok("User Deactivated Successfully.");
}

๐Ÿงฉ Pipeline Behaviors

1. Logging Behavior (Generic)

public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<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;
    }
}

2. Validation Behavior (Non-Generic)

public class ValidationBehavior<TRequest> : IPipelineBehavior<TRequest>
    where TRequest : IRequest
{
    public async Task HandleAsync(TRequest request, Func<Task> next, CancellationToken cancellationToken)
    {
        Console.WriteLine($"Validating {typeof(TRequest).Name}");
        await next();
    }
}

๐Ÿงช Unit Testing

Use xUnit + Shouldly for clean tests:

[Fact]
public async Task Dispatch_GenericRequest_ReturnsExpectedResponse()
{
    var services = new ServiceCollection();
    services.AddScoped<IRequestDispatcher, RequestDispatcher>();
    services.AddScoped<IRequestHandler<GetUserByIdQuery, UserResponse>, GetUserByIdHandler>();

    var provider = services.BuildServiceProvider();
    var dispatcher = provider.GetRequiredService<IRequestDispatcher>();

    var result = await dispatcher.SendAsync(new GetUserByIdQuery { Id = 1 });
    result.Name.ShouldBe("Jane Doe");
}

๐Ÿ“‚ Folder Structure Suggestion

src/
  CleanMediator/           --> NuGet package source
test/
  CleanMediator.Tests/     --> Unit tests with xUnit and Shouldly

๐Ÿ“œ License

This project is licensed under the MIT License.


๐Ÿค Contributing

Contributions are welcome! Please fork, fix, and submit a PR. Open issues if you have questions or suggestions.


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 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. 
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.1 203 4/15/2025
1.0.0 200 4/14/2025