NMediation 0.9.1

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

NMediation

Simple, easy mediation and publishing for dotnet.

TempIcon

build-status downloads nuget activity

Overview

NMediation gives you:

  • 📚 Simple and easy API
  • 💨 Fast & Performant
  • 🔀 Full async and Cancellation Token support
  • 💰 Free Forever
  • 🌱 Easily transition from MediatR

Table of Contents

Samples

If you would like code samples for NMediation, they may be found here in the documents.

Dependencies

NMediation has a dependency on the Microsoft.Extensions.DependencyInjection.Abstractions package to allow integration into the base container.

Installation

The easiest way to get started is to: Install with NuGet.

Install where you need with:

Install-Package NMediation

If you want to install just the base interfaces without the single dependency in certain projects.

Install-Package NMediation.Abstractions

Contents

NMediation is the simplest implementation of the Mediator and Observer patterns for the dotnet framework. The library comes with zero excessive features to weigh down performance or burden the end-user with unnecessary options.

The entire library consists of a series of interfaces alongside one base class and one type. It is purposely designed to allow a junior developer to learn in 15 minutes.

Quick Start

Setup

NMediation has a single line setup to hook itself into the base DI container.

services.AddNMedation(Assembly.GetExecutingAssembly());

...or if you have multiple projects to register, use the params argument.

services.AddNMedation(Assembly.GetExecutingAssembly(), Assembly.Load("OtherAssembly"));

Mediation

Mediation involves sending a request object to a single handler and returning a single response or a substitute for void.

It is recommended you always return an indicator to flag either the handler operation was a success or not.

Create a response object for your operation:

 public class WeatherResponse
 {
     public IEnumerable<string> Weather { get; init; } = Enumerable.Empty<string>();
 }

Create a request object that inherits the "IPayload" of type T where T is your response type.

public class WeatherRequest : IPayload<WeatherResponse>
{
}

As always, you may pass whatever metadata is required as a property.

Create a handler for the request object:

The handler will inherit from the "IPayloadHandler" interface of type T and K, where T is your request type and K is your response type.

public class WeatherHandler : IPayloadHandler<WeatherRequest, WeatherResponse>
{
    private readonly IWeatherSource _weatherSource;

    // Constructor omitted.

    public async Task<WeatherResponse> Handle(WeatherRequest payload, CancellationToken cancellationToken)
    {
        var currentWeather = await _weatherSource.GetCurrentWeather();

        return new WeatherResponse
        {
            Weather = currentWeather,
        };
    }
}

You may inject whatever dependencies are required for your handlers.

To start a mediation request, inject the "IMediation" interface into the source and send the request via the "Mediate" function.

// API Controller

public async Task<IActionResult> GetWeather()
{
    var result = await _medation.Mediate(new WeatherRequest());

    return Ok(result);
}

Publishing

Publishing involves sending an event to N number of handlers in a fire-and-forgot method with no return.

Create an event or occurrence to publish.

public class MyOccurrence : IOccurrence
{
}

The interface is to designate the type to determine which handlers to send the event to. You may add as much metadata as you require.

Create as many handlers as required to operate on the event.

Simply implement the "IOccurrenceHandler" of type T where T is the name of your event.

public class MyOccurrenceHandler : IOccurrenceHandler<MyOccurrence>
{
    public Task Handle(MyOccurrence occurrence, CancellationToken cancellationToken)
    {
        // Do whatever is required.
    }
}

To publish an event, call the "Publish" method on the "IMediation" interface.

var occurrence = new MyOccurrence();

await _medation.Publish(occurrence);

Detailed Usage

Pre- and post-processing handlers

NMediation comes with a built-in base handler that allows you to perform certain tasks before and after a handler's main task.

Let's say we want to log our payload and response object from certain handlers. That is a simple task to perform.

Have your logging handler inherit from the "BaseProcessingHandler" pass the type of your payload and response types like you would any other handler.

public abstract class BaseLoggingHandler : BaseProcessingHandler<WeatherRequest, WeatherResponse>
{
    private readonly ILogger<BaseLoggingHandler> _logger;

    public BaseLoggingHandler(ILogger<BaseLoggingHandler> logger)
    {
        _logger = logger;
    }

    protected override Task<WeatherRequest> PreProcessing(WeatherRequest payload, CancellationToken cancellationToken)
    {
        _logger.LogInformation("State of initial payload: {Payload}", payload);

        return Task.FromResult(payload);
    }

    protected abstract Task<WeatherResponse> DoWork(WeatherRequest payload, CancellationToken cancellationToken);

    protected override Task<WeatherResponse> PostProcessing(WeatherResponse response, CancellationToken cancellationToken)
    {
        _logger.LogInformation("State of final response: {Response}", response);

        return Task.FromResult(response);
    }
}

Your handler will implement your base handler and only implement the "DoWork" function.

public class MyWeatherHandler : BaseLoggingHandler
{
    public MyWeatherHandler(ILogger<BaseLoggingHandler> logger)
        : base(logger)
    {
    }

    protected override Task<string> DoWork(GetWeatherRequest payload, CancellationToken cancellationToken)
    {
        const string response = "The weather is hot!";

        return Task.FromResult(response);
    }
}

You may also continue to chain the generics down to the base handler to use in any situation.

public abstract class BaseGenericHandler<TRequest, TResponse> : BaseProcessingHandler<TRequest, TResponse>
    where TRequest : IPayload<TResponse>
{
    protected override Task<TResponse> PostProcessing(TResponse response, CancellationToken cancellationToken)
    {
        return Task.FromResult(response);
    }

    protected override Task<TRequest> PreProcessing(TRequest payload, CancellationToken cancellationToken)
    {
        return Task.FromResult(payload);
    }
}

Specific Pre- and Post-Processing handlers

There are also two extra base handlers will perform only pre- or post-processing operations.

public abstract class MyPreProcessingHandler : BasePreProcessingHandler<TRequest, TResponse>
{
    protected override Task<TRequest> PreProcessing(TRequest payload, CancellationToken cancellationToken)
    {
        // Implement method and return payload.
    }
}
public abstract class MyPostProcessingHandler : BasePostProcessingHandler<TRequest, TResponse>
{
    protected override Task<TResponse> PostProcessing(TResponse response, CancellationToken cancellationToken)
    {
        // Implment method and return response.
    }
}

Cancellation Token Support

You may pass a Cancellation token if you desire to either Mediation function, which will chain down to any handler.

var response = await _medation.Mediate(request, cancellationToken);

await _medation.Publish(occurrence, cancellationToken);

FAQ

Do I need NMediation?

You don't need any library. However, NMediation can be used in 99% of traditional applications. It does a great job at creating clear lines of separation between application level code and other parts of your project.

The other wonder side effect of NMediation is you can use feature folders for better project composition.

Does NMediation need a commercial license to use?

No! NMediation is 100% free forever. It uses the open source MIT license.

What are the main difference between NMediation and MediatR?

  • NMediation has simpler setup.
  • NMediation is blazing fast, with no excess ceremony.
  • NMediation only allows for fully typed contracts, no blank objects.
  • NMediation is free.
  • NMediation is easier to debug pre- and post-processing because it uses base classes for those operations.

Is it hard to transition over to NMediation?

Not at all, it is best to transition over time. You can convert one handler at a time until your application is fully converted.

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
0.9.1 152 2/13/2026
0.9.0 200 1/18/2026