MediatorForge 10.0.0

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

MediatorForge

Overview

MediatorForge is a lightweight, dependency injection‑friendly library for implementing CQRS and event‑driven patterns in .NET applications. It provides:

  • Command & Query dispatching with pipeline behaviors (logging, validation, etc.)
  • Event publishing to multiple handlers
  • Separate dispatcher interfaces for commands, queries, and events, plus a combined interface
  • Assembly scanning for automatic registration of handlers and behaviors

Features

  • Command and Query HandlingICommand<TResponse> / IQuery<TResponse> with dedicated handlers.
  • Event NotificationsIEventNotification<TEvent> and IEventNotificationHandler<TEvent> for pub/sub.
  • Pipeline Behaviors – Chainable behaviors (IPipelineBehavior<TRequest, TResponse>) for cross‑cutting concerns.
  • Multiple Dispatcher AbstractionsICommandDispatcher, IQueryDispatcher, IEventDispatcher, and combined IDispatcher.
  • Assembly Scanner – Auto‑register handlers and behaviors from any assembly.

Installation

Install the package via NuGet:

dotnet add package MediatorForge

Usage

1. Define Your Messages

Command (with response)
public class CreateUserCommand : ICommand<UserResponse>
{
    public string UserName { get; set; }
    public string Email { get; set; }
}

public class UserResponse
{
    public string UserName { get; set; }
    public string Email { get; set; }
    public string Status { get; set; }
}
Command (void / no response)
public class DeleteUserCommand : ICommand
{
    public Guid UserId { get; set; }
}
Query
public class GetUserQuery : IQuery<UserResponse>
{
    public string UserName { get; set; }
}
Event
public class UserRegisteredEvent
{
    public string UserName { get; set; }
    public DateTime RegisteredAt { get; set; }
}

2. Implement Handlers

Command Handler (with response)
public class CreateUserCommandHandler : IHandler<CreateUserCommand, UserResponse>
{
    public Task<UserResponse> HandleAsync(CreateUserCommand command, CancellationToken ct)
    {
        var response = new UserResponse
        {
            UserName = command.UserName,
            Email = command.Email,
            Status = "User Created Successfully"
        };
        return Task.FromResult(response);
    }
}
Command Handler (void)
public class DeleteUserCommandHandler : IHandler<DeleteUserCommand, Unit>
{
    public Task<Unit> HandleAsync(DeleteUserCommand command, CancellationToken ct)
    {
        // deletion logic
        return Task.FromResult(Unit.Value);
    }
}
Query Handler
public class GetUserQueryHandler : IHandler<GetUserQuery, UserResponse>
{
    public Task<UserResponse> HandleAsync(GetUserQuery query, CancellationToken ct)
    {
        var response = new UserResponse
        {
            UserName = query.UserName,
            Email = $"{query.UserName}@example.com",
            Status = "User Retrieved Successfully"
        };
        return Task.FromResult(response);
    }
}
Event Handler
public class UserRegisteredEventHandler : IEventNotificationHandler<UserRegisteredEvent>
{
    public Task HandleAsync(IEventNotification<UserRegisteredEvent> notification, CancellationToken ct)
    {
        var eventData = notification.Event;
        Console.WriteLine($"User registered: {eventData.UserName} at {eventData.RegisteredAt}");
        return Task.CompletedTask;
    }
}

3. Pipeline Behaviors (Optional)

Behaviors wrap the handler execution. They implement IPipelineBehavior<TRequest, TResponse> and are executed in the order they are registered (last registered runs first, wrapping the innermost handler).

Example: Logging Behavior
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    public async Task<TResponse> HandleAsync(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken ct)
    {
        var requestName = typeof(TRequest).Name;
        Debug.WriteLine($"Handling {requestName}");

        var response = await next();

        Debug.WriteLine($"Handled {requestName}");
        return response;
    }
}

4. Dependency Injection Setup

In your Startup or Program:

using MediatorForge;
using MediatorForge.Abstractions;

var services = new ServiceCollection();

// Add core dispatcher (combined)
services.AddCqrs();

// Register handlers (commands, queries) from an assembly
services.AddHandlersFromAssemblyContaining<CreateUserCommandHandler>();

// Register event handlers from an assembly
services.AddEventHandlersFromAssemblyContaining<UserRegisteredEventHandler>();

// Register pipeline behaviors from an assembly
services.AddPipelineBehaviorsFromAssemblyContaining<LoggingBehavior<,>>();

// Build provider
var serviceProvider = services.BuildServiceProvider();

Note: The AddCqrs() method registers the Dispatcher as IDispatcher, ICommandDispatcher, IQueryDispatcher, and IEventDispatcher simultaneously. You can inject any of these interfaces.

5. Dispatching

Using the combined IDispatcher
public class SomeService
{
    private readonly IDispatcher _dispatcher;

    public SomeService(IDispatcher dispatcher)
    {
        _dispatcher = dispatcher;
    }

    public async Task DoWork()
    {
        // Send command with response
        var user = await _dispatcher.SendAsync<CreateUserCommand, UserResponse>(
            new CreateUserCommand { UserName = "john", Email = "john@example.com" });

        // Send void command
        await _dispatcher.SendAsync(new DeleteUserCommand { UserId = Guid.NewGuid() });

        // Query
        var retrieved = await _dispatcher.QueryAsync<GetUserQuery, UserResponse>(
            new GetUserQuery { UserName = "john" });

        // Publish event
        await _dispatcher.PublishAsync(new UserRegisteredEvent("john", DateTime.UtcNow));
    }
}
Using segregated dispatchers (better separation of concerns)
public class CommandService
{
    private readonly ICommandDispatcher _commandDispatcher;
    public CommandService(ICommandDispatcher commandDispatcher) => _commandDispatcher = commandDispatcher;
    // only SendAsync methods visible
}

public class QueryService
{
    private readonly IQueryDispatcher _queryDispatcher;
    public QueryService(IQueryDispatcher queryDispatcher) => _queryDispatcher = queryDispatcher;
    // only QueryAsync visible
}

public class EventService
{
    private readonly IEventDispatcher _eventDispatcher;
    public EventService(IEventDispatcher eventDispatcher) => _eventDispatcher = eventDispatcher;
    // only PublishAsync visible
}

Dispatcher Interfaces

Interface Methods Purpose
ICommandDispatcher SendAsync<TCommand, TResponse><br/>SendAsync<TCommand> One‑to‑one command handling
IQueryDispatcher QueryAsync<TQuery, TResponse> One‑to‑one query handling
IEventDispatcher PublishAsync<TEvent> One‑to‑many event notification
IDispatcher All of the above Combined convenience

How It Works

  • The Dispatcher class resolves the appropriate handler from the DI container.
  • Pipeline behaviors are chained in reverse registration order (last registered wraps the handler).
  • For events, all handlers are invoked sequentially (order can be controlled by registration order).
  • Commands and queries follow a one‑to‑one pattern; events follow a one‑to‑many pattern.

Advanced Configuration

Changing Handler/Behavior Lifetimes

By default, AddHandlersFromAssemblyContaining, AddEventHandlersFromAssemblyContaining, and AddPipelineBehaviorsFromAssemblyContaining register services as Transient. You can change the lifetime:

services.AddHandlersFromAssemblyContaining<MyHandler>(ServiceLifetime.Scoped);
services.AddEventHandlersFromAssemblyContaining<MyEventHandler>(ServiceLifetime.Singleton);

Sequential vs. Parallel Event Handling

The default Dispatcher.PublishAsync processes event handlers sequentially (one after another). If you prefer parallel execution, modify the method:

var tasks = handlers.Select(h => h.HandleAsync(notification, ct));
await Task.WhenAll(tasks);

License

This project is licensed under the MIT License.

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 (1)

Showing the top 1 NuGet packages that depend on MediatorForge:

Package Downloads
MediatorForge.Adapters

MediatorForge.Adapters provides a seamless integration of MediatorForge validators with custom validation systems in C# applications. Key Features: - Provides adapters to connect MediatorForge validation with custom systems. - Ensures consistent validation logic across different layers. - Simplifies integration and enhances code maintainability. This library is designed to work with MediatorForge, ensuring smooth and efficient validation processes in your applications.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.0.0 93 4/3/2026
1.1.0 226 1/31/2025
1.0.6 182 1/31/2025
1.0.5 184 12/31/2024
1.0.4 168 12/31/2024
1.0.3 161 12/31/2024
1.0.2 232 12/25/2024
1.0.1 217 12/6/2024
1.0.0 197 11/30/2024