Mediatr.Patterns.Builder
8.0.0
dotnet add package Mediatr.Patterns.Builder --version 8.0.0
NuGet\Install-Package Mediatr.Patterns.Builder -Version 8.0.0
<PackageReference Include="Mediatr.Patterns.Builder" Version="8.0.0" />
paket add Mediatr.Patterns.Builder --version 8.0.0
#r "nuget: Mediatr.Patterns.Builder, 8.0.0"
// Install Mediatr.Patterns.Builder as a Cake Addin #addin nuget:?package=Mediatr.Patterns.Builder&version=8.0.0 // Install Mediatr.Patterns.Builder as a Cake Tool #tool nuget:?package=Mediatr.Patterns.Builder&version=8.0.0
MediatR.Patterns.Builder
MediatR.Patterns.Builder Sits on top of MediatR and exposes PreProcess, Process and PostProcess methods to handlers instead of only exposing the Handle method allowing to implement handlers using the builder pattern.
It simplifies common usage of Mediatr integrating interfaces to differentiate between commands and queries and also automatically creating a behavior pipeline to apply FluentValidation checks.
It is as fast as the vanilla version and helps reduce the development process by having a defined pattern within handlers.
Usage
Handlers
Inherit from the abstract class BuilderRequestHandler setting what the request and the response are.
In below example, if the cache has a value, it returns from the PreProcess
method directly without going to the Process
method but
if not (and returns null
) the Process
method and then PostProcess
method will execute in sequence.
public class GetAllCountriesHandler : BuilderRequestHandler<GetAllCountries, List<CountryData>>
{
private readonly ILogger<GetAllCountriesHandler> _logger;
private readonly ICache _cache;
private readonly IRepository _repository;
public GetAllCountriesHandler(ICache cache, ILogger<GetAllCountriesHandler> logger, IRepository repository)
{
_logger = logger;
_cache = cache;
_repository = repository;
}
protected override async Task<List<CountryData>> PreProcess(GetAllCountries request, CancellationToken cancellationToken = default)
{
var cacheKey = GetCacheKey();
var cachedValue = await _cache.GetCacheValueAsync<List<CountryData>>(cacheKey, cancellationToken);
if (cachedValue == null) return null;
_logger.LogInformation("Cache value found for {CacheKey}", cacheKey);
return cachedValue;
}
protected override async Task<List<CountryData>> Process(GetAllCountries request, CancellationToken cancellationToken = default)
{
return await GetAllCountries();
}
protected override Task PostProcess(GetAllCountries request, List<CountryData> response, CancellationToken cancellationToken = default)
{
if (response != null)
{
_ = _cache.SetCacheValueAsync(GetCacheKey(), response, cancellationToken);
}
return Task.CompletedTask;
}
}
Differentiate between Query and Command
- For queries instead of using
IRequest
useIQuery
- For commands instead of using
IRequest
useICommand
By doing this can further expand your pipeline behaviors and act according to the type of request.
public class GetAllCountries : IQuery<List<CountryData>>
{
... some properties
}
public class AddCountry : ICommand<List<CountryData>>
{
... some properties
}
Setting FluentValidation
Just create the validations related to the request you will be handling like you normally do:
public class GetAllCountries : IQuery<List<CountryData>>
{
... some properties
}
public class GetAllCitiesValidator : AbstractValidator<GetAllCountries>
{
public GetAllCitiesValidator()
{
RuleFor(x => x).NotNull();
... more fluentValidation rules
}
}
Configuration
Dependency Injection
Just as Mediatr, you can pass the assemblies to scan for handlers and those assemblies can be also used by FluentValidation if AddFluentValidation
is set to true so it internally creates a pipeline behavior to validate before going to the handler.
services.AddMediatrBuilder(options =>
{
options.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly(), ... more assemblies)
options.AddFluentValidation(true);
});
Contributing
It is simple, as all things should be:
- Clone it
- Improve it
- Make pull request
Credits
- Initial development by Slukad
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. 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. |
-
net8.0
- FluentValidation.DependencyInjectionExtensions (>= 11.8.0)
- MediatR (>= 12.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Release