Zwergenland.CleanMediator
1.1.1
dotnet add package Zwergenland.CleanMediator --version 1.1.1
NuGet\Install-Package Zwergenland.CleanMediator -Version 1.1.1
<PackageReference Include="Zwergenland.CleanMediator" Version="1.1.1" />
<PackageVersion Include="Zwergenland.CleanMediator" Version="1.1.1" />
<PackageReference Include="Zwergenland.CleanMediator" />
paket add Zwergenland.CleanMediator --version 1.1.1
#r "nuget: Zwergenland.CleanMediator, 1.1.1"
#:package Zwergenland.CleanMediator@1.1.1
#addin nuget:?package=Zwergenland.CleanMediator&version=1.1.1
#tool nuget:?package=Zwergenland.CleanMediator&version=1.1.1
CleanMediatR
This package will provide similar features like the (now paid) MediatR Package and can be combined with the CleanDomainValidation package to return strongly typed errors instead of exceptions.
IT also makes implementing CQRS more easy as commands, queries and events can be seperated by default
Defining handlers
For each of the three types a request object and a request handler must be defined. The request object contains all necessary information as described in the CleanDomainValidation package. While Queries must contain a return type, Commands can be implemented without one for write only commands. Events can never have a return type as they have no real caller that can handle those information.
For defining request objects, simply inherit from the marker interfaces:
ICommand
for command without responseICommand<TResult>
for commands with response of typeTResult
IQuery<TResult>
for query with response of typeTResult
IEvent
for an event
For handling the specified request, a command handler must be created by inheriting from the following bases:
CommandHandlerBase<TCommand>
for command of typeTCommand
without a responseCommandHandlerBase<TCommand, TResult>
for command of typeTCommand
with response of typeTResult
QueryHandlerBase<TQuery, TResult>
for query of typeTQuery
with response of typeTResult
CommandHandlerBase<TEvent>
for event of typeTEvent
Example for command with response:
public class AddUserCommandHandler : CommandHandlerBase<AddUserCommand, AddUserResult>
{
public Task<CanFail<AddUserResult>> Handle(AddUserCommand command, CancellationToken cancellationToken)
{
//command logic that may result in error
}
}
Example for command without response:
public class UserDataUpdatedEventHandler : EventHandlerBase<UserDataUpdatedEvent>
{
public Task<CanFail> Handle(UserDataUpdatedEvent @event, CancellationToken cancellationToken)
{
//command logic that may result in error
}
}
Register handlers automatically
To automatically register the handlers to the Dependency Injection can be accomplished by
calling AddCleanMediator
and defining the assemblies to register. Registering multiple assemblies
is also supported.
Example:
builder.Services.AddCleanMediator(cfg =>
{
cfg.RegisterServicesFromAssembly(typeof(UserDataUpdatedEventHandler).GetExecutingAssembly());
});
Execute handlers
To execute the registered handlers, the IMediator
interface can be used
with the following methods:
mediator.ExecuteAsync(command)
for command without responsemediator.ExecuteAsync<TResult>(command)
for command with response of typeTResult
mediator.RunAsync<TResult>(query
for queries with response of typeTResult
mediator.PublishAsync(@event)
for events
The calls will be handles asynchronously and the result is a Result object of type
CanFail
for handlers without a result and CanFail<TResult>
for handlers that return TResult
.
Example:
var command = new AddUserCommand(); //Of type ICommand<AddUserResult>
var result = await mediator.ExecuteAsync(command); //Returns CanFail<AddUserResult>
//handle result
Specify generic request
For generic requests, the IRequest
and IRequest<TResult>
interface can be used
to mark the request object.
The handler can be implemented by creating a class inheriting from IRequestHandler<TRequest>
or IRequestHandler<TRequest, TResult>
just like in the examples above.
Generic requests can be executed by calling mediator.SendAsync(...)
or mediator.SendAsync<TResult>(...)
.
Sending requests without a scope
In some cases the request will be processed in the background and thus no service scope is set
even it may be required. This is especially often the case for events as they have no natural caller.
To make the life of the developer more easy, the service provider extension
CreateAsyncMediatorScope()
can be used to create a separate service scope that can be used just
like a normal mediator. All calls made to the returned AsyncMediatorScope
will be handled in
the same scope.
Example:
await scope = serviceProvider.CreateAsyncMediatorScope();
//Those two handlers will be executed in the same scope
var res1 = await scope.PublishAsync(event1);
var res2 = await scope.PublishAsync(event2);
await scope = serviceProvider.CreateAsyncMediatorScope();
//This handler will be executed in a seperate scope
var res3 = await scope.PublishAsync(event3);
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. 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. |
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.6)
- Zwergenland.CleanDomainValidation (>= 1.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.