EasyRequestHandler 1.1.3

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

Easy Request Handler

EasyRequestHandler is a lightweight and extensible .NET library that simplifies request and event handling using patterns like Mediator and Event Dispatcher. It integrates seamlessly with the .NET Dependency Injection (DI) system and supports asynchronous operations, making it ideal for modular applications and event-driven systems.

✨ Features

  • Mediator Pattern: Centralizes request handling with support for request pre/post hooks and behaviors (middleware).
  • Flexible Request Handling: Use RequestHandler<TRequest, TResponse> or RequestHandler<TResponse> base classes.
  • Event Dispatching: Handle and publish events using IEventHandler<TEvent>.
  • Automatic Registration: Register all handlers with a single method using IServiceCollection extensions.

📦 Installation

Install from NuGet using the following command:

Install-Package EasyRequestHandler

🚀 Usage

🧭 Request Handling

Basic Request Handlers

Handlers can be used in two ways:

  • Direct Injection: Inject the handler class itself (e.g., MyRequestHandler) into your controller or service and call HandleAsync() directly.
  • Mediator Pattern: Use the ISender interface to decouple request handling and improve testability and separation of concerns.

Here’s how you could invoke a request using the ISender interface:

public class MyApiController : ControllerBase
{
    private readonly ISender _sender;

    public MyApiController(ISender sender)
    {
        _sender = sender;
    }

    [HttpGet("double")]
    public async Task<IActionResult> GetDoubledNumber([FromQuery] int number)
    {
        var response = await _sender.SendAsync<MyRequest, MyResponse>(new MyRequest { Number = number });
        return Ok(response.Result);
    }
}

Define a request and handler:

public class MyRequest
{
    public int Number { get; set; }
}

public class MyResponse
{
    public int Result { get; set; }
}

public class MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
    public override Task<MyResponse> HandleAsync(MyRequest request, CancellationToken cancellationToken = default)
    {
        return Task.FromResult(new MyResponse { Result = request.Number * 2 });
    }
}

For handlers with no input request:

public class WeatherForecastHandler : RequestHandler<List<WeatherForecast>>
{
    public override Task<List<WeatherForecast>> HandleAsync(CancellationToken cancellationToken = default)
    {
        return Task.FromResult(GetForecasts());
    }
}
Mediator Pattern

Use the ISender interface to decouple request invocation:

public async Task<IActionResult> GetForecast(string city, ISender sender)
{
    var forecast = await sender.SendAsync<string, WeatherForecast>(city);
    return Ok(forecast);
}
Request Behaviors

Behaviors are middleware for requests:

public class LoggingBehaviour<TRequest, TResponse> : IPipelineBehaviour<TRequest, TResponse>
{
    private readonly ILogger<LoggingBehaviour<TRequest, TResponse>> _logger;

    public LoggingBehaviour(ILogger<LoggingBehaviour<TRequest, TResponse>> logger)
    {
        _logger = logger;
    }

    public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
    {
        _logger.LogInformation("Handling {RequestType}", typeof(TRequest).Name);
        var response = await next();
        _logger.LogInformation("Handled {RequestType}", typeof(TRequest).Name);
        return response;
    }
}
Request Hooks

The library now supports three different types of hooks to provide more flexibility in your request processing pipeline:

// Complete hook (both pre and post execution)
public class MyRequestHook : IRequestHook<MyRequest, MyResponse>
{
    public Task OnExecutingAsync(MyRequest request, CancellationToken cancellationToken)
    {
        Console.WriteLine("Before handling request");
        return Task.CompletedTask;
    }

    public Task OnExecutedAsync(MyRequest request, MyResponse response, CancellationToken cancellationToken)
    {
        Console.WriteLine("After handling request");
        return Task.CompletedTask;
    }
}

// Pre-execution only hook
public class MyRequestPreHook : IRequestPreHook<MyRequest>
{
    public Task OnExecutingAsync(MyRequest request, CancellationToken cancellationToken)
    {
        Console.WriteLine("Pre-hook executing");
        // You can modify request properties here
        return Task.CompletedTask;
    }
}

// Post-execution only hook
public class MyRequestPostHook : IRequestPostHook<MyRequest, MyResponse>
{
    public Task OnExecutedAsync(MyRequest request, MyResponse response, CancellationToken cancellationToken)
    {
        Console.WriteLine("Post-hook executed");
        // You can work with both request and response here
        return Task.CompletedTask;
    }
}
Registration and Configuration
services.AddEasyRequestHandlers(typeof(Program))
        .WithMediatorPattern()
        .WithBehaviours(typeof(LoggingBehaviour<,>), typeof(ValidationBehaviour<,>))
        .WithRequestHooks()
        .Build();

Minimal API example:

//Using direct handler injection.
app.MapGet("/weather-forecast", async (WeatherRequest request, WeatherForecastHandler handler) =>
{
    return await handler.HandleAsync(request);
});

//Using Mediator Pattern
app.MapGet("/weather-forecast", async (WeatherRequest request, ISender sender) =>
{
    return await sender.SendAsync<WeatherRequest, WeatherForecast?>(request, cancellationToken: cancellationToken);
});

📣 Event Handling

A single event can have multiple handlers. All handlers registered for an event will be invoked, and they can run either sequentially or in parallel depending on the event publisher's implementation.

Basic Event Handler
public class MyEvent
{
    public string Message { get; set; }
}

public class MyEventHandler : IEventHandler<MyEvent>
{
    public Task HandleAsync(MyEvent @event, CancellationToken cancellationToken)
    {
        Console.WriteLine(@event.Message);
        return Task.CompletedTask;
    }
}
Publishing Events
public class MyController
{
    private readonly IEventPublisher _publisher;

    public MyController(IEventPublisher publisher)
    {
        _publisher = publisher;
    }

    public async Task SendNotification(string message)
    {
        await _publisher.PublishAsync(new MyEvent { Message = message });
    }
}

✅ Summary

EasyRequestHandler provides a clean, extensible way to manage requests and events in .NET, with support for modern patterns like mediator, behaviors, and hooks—all without unnecessary boilerplate.


Licensed under MIT.

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.1.3 455 7/23/2025
1.1.2 149 7/16/2025
1.1.1 144 7/8/2025
1.1.0 144 7/7/2025
1.0.9 139 7/7/2025
1.0.8 90 7/5/2025
1.0.7 348 4/10/2025
1.0.6 177 4/10/2025
1.0.4 1,294 9/2/2024
1.0.3 127 8/30/2024
1.0.2 127 8/30/2024
1.0.1 130 8/30/2024
1.0.0 139 8/30/2024