Handly 1.0.2
dotnet add package Handly --version 1.0.2
NuGet\Install-Package Handly -Version 1.0.2
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="Handly" Version="1.0.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Handly" Version="1.0.2" />
<PackageReference Include="Handly" />
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 Handly --version 1.0.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Handly, 1.0.2"
#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 Handly@1.0.2
#: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=Handly&version=1.0.2
#tool nuget:?package=Handly&version=1.0.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Handly
Handly is a lightweight and transparent mediator-style dispatcher for .NET. Inspired by MediatR, it aims to be faster, leaner, and open-source.
🚀 Benchmarks
Performed on a MacBook M1 Pro (.NET 9, BenchmarkDotNet, Release build)
Method | Mean | StdDev | Ratio | Allocated |
---|---|---|---|---|
MediatR.Send (no behaviors) | 77.24 ns | 0.65 ns | baseline | 288 B |
Handly.Dispatch (no behaviors) | 103.92 ns | 1.28 ns | +35% | 264 B |
MediatR.Send (with behaviors) | 270.31 ns | 4.53 ns | +250% | 1072 B |
Handly.Dispatch (with behaviors) | 635.12 ns | 7.28 ns | +722% | 864 B |
✅ Why Handly?
- Open-source and Free — no license cost, forever.
- Transparent and Hackable — know what runs and why.
- Performant — especially with no behaviors.
- No Reflection at Runtime — compiled, cached, and minimal allocations.
✨ Features
- Lightweight
Dispatcher
forIRequest<TResponse>
- Pipeline behaviors (logging, validation, metrics...)
- Assembly scanning for handler auto-registration
- Plug-and-play DI integration
- Dead simple API and structure
📦 Installation
dotnet add package Handly
Or via NuGet:
👋 Getting Started
1. Define a Request
public class Ping : IRequest<string> { }
2. Create a Handler
public class PingHandler : IRequestHandler<Ping, string>
{
public Task<string> Handle(Ping request, CancellationToken cancellationToken)
{
return Task.FromResult("Pong");
}
}
3. (Optional) Add a Behavior
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;
public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)
{
_logger = logger;
}
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TRequest, TResponse> next,
CancellationToken cancellationToken)
{
_logger.LogInformation($"Handling {typeof(TRequest).Name}");
var response = await next();
_logger.LogInformation($"Handled {typeof(TRequest).Name}");
return response;
}
}
4. Register with DI
builder.Services.AddHandly(cfg =>
{
cfg.RegisterHandlerFromAssembly(Assembly.GetExecutingAssembly());
cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
});
5. Dispatch a request
public class MyService
{
private readonly IDispatcher _dispatcher;
public MyService(IDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public async Task ExecuteAsync()
{
var request = new Ping();
var response = await _dispatcher.Dispatch(request);
Console.WriteLine(response); // Pong
}
}
❤️ Contributing
Pull requests are welcome! For major changes, please open an issue first.
🔒 License
MIT. Free as in freedom.
Made with ❤️ by developer who like things fast and clean.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | 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 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.
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.4)
- Microsoft.Extensions.Hosting (>= 9.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.