ETPackages.Mediator is a simple and performance-oriented library for .NET. It supports IRequest, INotification, IPipelineBehavior, and works seamlessly with Dependency Injection.
- β
Request/Response (
IRequest,IRequest<TResponse>) - β
Notifications (
INotification) - β
Pipeline behaviors (
IPipelineBehavior) - β Dependency Injection ready
- β Fully async support
- .NET 8.0 or higher
Install via NuGet:
Install-Package ETPackages.Mediator
Or via the .NET Core command line interface:
dotnet add package ETPackages.Mediator
using ETPackages.Mediator;
services.AddMediator(options =>
{
options.AddRegisterAssemblies(typeof(Program).Assembly);
options.AddOpenBehavior(typeof(LoggingBehavior<,>)); //with response
options.AddOpenBehavior(typeof(ValidationBehavior<,>)); //with response
options.AddOpenBehavior(typeof(ValidationBehavior<>)); //no response
});Define a request and its corresponding handler:
With Response
public class GetProductQuery : IRequest<ProductDto>
{
public int Id { get; set; }
}
public class GetProductQueryHandler : IRequestHandler<GetProductQuery, ProductDto>
{
public Task<ProductDto> Handle(GetProductQuery request, CancellationToken cancellationToken)
{
var product = new ProductDto { Id = request.Id, Title = "Domain-Driven Design: Tackling Complexity in the Heart of Software" };
return Task.FromResult(product);
}
}No Response
public class CreateProductCommand : IRequest
{
public string Title { get; set; }
}
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand>
{
public Task Handle(CreateProductCommand request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
// db record
await Task.CompletedTask;
}
}Use IMediator to send the request:
With Response
var result = await mediator.Send(new GetProductQuery { Id = 1 });
Console.WriteLine(result.Title);No Response
await mediator.Send(new CreateProductCommand { Title = "Domain-Driven Design: Tackling Complexity in the Heart of Software" });Use IPipelineBehavior for cross-cutting concerns like logging, validation, caching, etc.
With Response
public interface ILoggableRequest
{
}
public class LoggingBehavior<TRequest, TResponse>(ILogger<LoggingBehavior<TRequest, TResponse>> logger) : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>, ILoggableRequest
{
public async Task<TResponse> Handle(TRequest request, RequesteHandlerDelete<TResponse> next, CancellationToken cancellationToken)
{
var requestName = typeof(TRequest).Name;
logger.LogInformation($"Request received: {requestName}");
var response = await next();
logger.LogInformation($"Response returned: {requestName}");
return response;
}
}No Response
public class ValidationBehavior<TRequest>(ILogger<ValidationBehavior<TRequest>> logger) : IPipelineBehavior<TRequest>
where TRequest : IRequest
{
public async Task Handle(TRequest request, RequesteHandlerDelete<TResponse> next, CancellationToken cancellationToken)
{
var requestName = typeof(TRequest).Name;
logger.LogInformation($"Request validation started: {requestName}");
await next();
logger.LogInformation($"Request validation finished: {requestName}");
}
}Define a notification and its handler:
public class ProductCreatedEvent : INotification
{
public ProductCreatedEvent(int id)
{
Id = id;
}
public int Id { get; set; }
}
public class SendEmailHandler(ILogger<SendEmailHandler> logger) : INotificationHandler<ProductCreatedEvent>
{
public Task Handle(ProductCreatedEvent notification, CancellationToken cancellationToken)
{
logger.LogInformation($"Id sent: {notification.Id}");
// process send email
return Task.CompletedTask;
}
}Publish a notification:
await mediator.Publish(new ProductCreatedEvent(product.Id));This project is licensed under the MIT License.