EasyDispatch 1.0.7
dotnet add package EasyDispatch --version 1.0.7
NuGet\Install-Package EasyDispatch -Version 1.0.7
<PackageReference Include="EasyDispatch" Version="1.0.7" />
<PackageVersion Include="EasyDispatch" Version="1.0.7" />
<PackageReference Include="EasyDispatch" />
paket add EasyDispatch --version 1.0.7
#r "nuget: EasyDispatch, 1.0.7"
#:package EasyDispatch@1.0.7
#addin nuget:?package=EasyDispatch&version=1.0.7
#tool nuget:?package=EasyDispatch&version=1.0.7
EasyDispatch
A lightweight, simple Mediator library for .NET focused on ease-of-use and implementing the CQRS pattern.
Features
Simple API - Minimal boilerplate, intuitive API
CQRS Support - Clean separation of queries, commands, and notifications
Streaming Queries - Handle large datasets efficiently with IAsyncEnumerable
Pipeline Behaviors - Add cross-cutting concerns like logging and validation
Polymorphic Dispatch - Notifications handled by base class and interface handlers
Startup Validation - Catch missing handlers at application startup
OpenTelemetry Support - Built-in Activity tracing for observability
Installation
dotnet add package EasyDispatch
Quick Start
1. Register the Mediator
var builder = WebApplication.CreateBuilder(args);
// Register mediator and scan assembly for handlers
builder.Services.AddMediator(typeof(Program).Assembly);
var app = builder.Build();
2. Define a Query and Handler
// Query
public record GetUserQuery(int UserId) : IQuery<UserDto>;
// Handler
public class GetUserQueryHandler : IQueryHandler<GetUserQuery, UserDto>
{
private readonly IUserRepository _repository;
public GetUserQueryHandler(IUserRepository repository)
{
_repository = repository;
}
public async Task<UserDto> Handle(GetUserQuery query, CancellationToken cancellationToken)
{
var user = await _repository.GetByIdAsync(query.UserId, cancellationToken);
return new UserDto(user.Id, user.Name, user.Email);
}
}
3. Use the Mediator
public class UserController : ControllerBase
{
private readonly IMediator _mediator;
public UserController(IMediator mediator) => _mediator = mediator;
[HttpGet("{id}")]
public async Task<ActionResult<UserDto>> GetUser(int id)
{
var query = new GetUserQuery(id);
var user = await _mediator.SendAsync(query);
return Ok(user);
}
}
Message Types
Queries - Read operations that return data
public record GetUserQuery(int UserId) : IQuery<UserDto>;
Commands - Write operations that modify state
public record CreateUserCommand(string Name, string Email) : ICommand<int>;
public record DeleteUserCommand(int UserId) : ICommand;
Notifications - Events with multiple handlers (pub/sub)
public record UserCreatedNotification(int UserId, string Name) : INotification;
Streaming Queries - Large datasets returned incrementally
public record GetOrdersStreamQuery(int PageSize) : IStreamQuery<OrderDto>;
Pipeline Behaviors
Add cross-cutting concerns like logging, validation, and caching:
builder.Services.AddMediator(typeof(Program).Assembly)
.AddOpenBehavior(typeof(LoggingBehavior<,>))
.AddOpenBehavior(typeof(ValidationBehavior<,>))
.AddOpenBehavior(typeof(PerformanceBehavior<,>));
Configuration
builder.Services.AddMediator(options =>
{
// Assemblies to scan
options.Assemblies = new[] { typeof(Program).Assembly };
// Handler lifetime (default: Scoped)
options.HandlerLifetime = ServiceLifetime.Scoped;
// Notification strategy (default: StopOnFirstException)
options.NotificationPublishStrategy = NotificationPublishStrategy.ParallelWhenAll;
// Startup validation (default: None)
options.StartupValidation = StartupValidation.FailFast;
});
Documentation
Examples
Command with Response
public record CreateOrderCommand(
int CustomerId,
List<OrderItem> Items
) : ICommand<int>;
public class CreateOrderCommandHandler : ICommandHandler<CreateOrderCommand, int>
{
public async Task<int> Handle(CreateOrderCommand command, CancellationToken ct)
{
var order = new Order { CustomerId = command.CustomerId, Items = command.Items };
await _repository.AddAsync(order, ct);
return order.Id;
}
}
// Usage
var command = new CreateOrderCommand(customerId: 123, items);
int orderId = await mediator.SendAsync(command);
Notifications with Multiple Handlers
public record UserCreatedNotification(int UserId, string Email) : INotification;
// Handler 1: Send welcome email
public class SendWelcomeEmailHandler : INotificationHandler<UserCreatedNotification>
{
public async Task Handle(UserCreatedNotification notification, CancellationToken ct)
{
await _emailService.SendWelcomeEmailAsync(notification.Email, ct);
}
}
// Handler 2: Update analytics
public class UpdateAnalyticsHandler : INotificationHandler<UserCreatedNotification>
{
public async Task Handle(UserCreatedNotification notification, CancellationToken ct)
{
await _analyticsService.TrackUserCreatedAsync(notification.UserId, ct);
}
}
// Usage - both handlers execute
await mediator.PublishAsync(new UserCreatedNotification(userId, email));
Streaming Large Datasets
public record GetOrdersStreamQuery() : IStreamQuery<OrderDto>;
public class GetOrdersStreamQueryHandler : IStreamQueryHandler<GetOrdersStreamQuery, OrderDto>
{
public async IAsyncEnumerable<OrderDto> Handle(
GetOrdersStreamQuery query,
[EnumeratorCancellation] CancellationToken ct)
{
await foreach (var order in _repository.StreamAllOrdersAsync(ct))
{
yield return new OrderDto(order.Id, order.Total);
}
}
}
// Usage - process items as they arrive
await foreach (var order in mediator.StreamAsync(new GetOrdersStreamQuery()))
{
Console.WriteLine($"Order {order.Id}: ${order.Total}");
}
Requirements
- .NET 9.0 or later
- Microsoft.Extensions.DependencyInjection 9.0+
License
This project is licensed under the MIT License - see the LICENSE file for details.
| 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. |
-
net9.0
- Microsoft.Extensions.DependencyInjection (>= 9.0.9)
- Microsoft.Extensions.Logging (>= 9.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.