Dekiru.Hermes.Generator
0.0.1
Prefix Reserved
Original package published under wrong name
dotnet add package Dekiru.Hermes.Generator --version 0.0.1
NuGet\Install-Package Dekiru.Hermes.Generator -Version 0.0.1
<PackageReference Include="Dekiru.Hermes.Generator" Version="0.0.1" />
<PackageVersion Include="Dekiru.Hermes.Generator" Version="0.0.1" />
<PackageReference Include="Dekiru.Hermes.Generator" />
paket add Dekiru.Hermes.Generator --version 0.0.1
#r "nuget: Dekiru.Hermes.Generator, 0.0.1"
#:package Dekiru.Hermes.Generator@0.0.1
#addin nuget:?package=Dekiru.Hermes.Generator&version=0.0.1
#tool nuget:?package=Dekiru.Hermes.Generator&version=0.0.1
Hermes - A messenger to the gods
Hermes is an implementation of the mediator pattern for .NET. It uses source generators to create a dispatcher for queries, commands and events.
How to use: Add
Dekiru.Hermesto your project and register the generated dispatcher in your DI container. Registration is done via theAddHermesextension method onIServiceCollection. (As such, Hermes requiresMicrosoft.Extensions.DependencyInjection.)
The most basic usage is as follows:
[Handler]
public class MyHandler : IQueryHandler<MyQuery, MyResponse>
{
public Task<MyResponse> Handle(MyQuery query, CancellationToken cancellationToken)
{
return Task.FromResult(new MyResponse());
}
}
This will generate a Dispatch-method on the IDispatcher interface that takes a MyQuery and returns a Task<MyResponse>.
There are four types of interfaces that can be used to define handlers:
ICommandHander<TCommand>- Handles commands that do not return a value.ICommandHandler<TCommand, TResponse>- Handles commands that return a value.IQueryHandler<TQuery, TResponse>- Handles queries that return a value.IEventHandler<TEvent>- Handles events that do not return a value. Multiple event handlers can be defined for the same event. Errors thrown by one handler will be ignored and the other handlers will still be executed.
Note on
ICommandHandler<TCommand>: This interface is functionally identical toICommandHandler<TCommand, Null>, whereNullis a class representing a void return type. The choice between the two is primarily a matter of preference and code clarity. TheDispatch-method generated forICommandHandler<TCommand>will return aTask, while the one forICommandHandler<TCommand, TResponse>will return aTask<TResponse>. Handlers implementingICommandHandler<TCommand>may be more readable in scenarios where the command does not need to return a value, as it clearly indicates that no response is expected. The developer can returnNull.Taskto reduce unnecessary allocations.
Beyond the handler interfaces, there's also an interface for middleware (IMiddleware<TRequest, TResponse>). Middleware can be used to add cross-cutting concerns to the dispatching process, such as logging, validation, or transaction management. Middleware is executed in the order it is registered on the handler.
[Handler]
[Middleware<MyMiddleware>]
public class MyHandler : IQueryHandler<MyQuery, MyResponse>
{
...
}
Middleware implements a Handle(TRequest request, Func<TRequest, CancellationToken, Task<TResponse>> next, CancellationToken cancellationToken) method. The next parameter is a delegate that invokes the next middleware in the pipeline, or the handler if there are no more middleware.
public class MyMiddleware : IMiddleware<MyQuery, MyResponse>
{
public async Task<MyResponse> Handle(MyQuery request, Func<MyQuery, CancellationToken, Task<MyResponse>> next, CancellationToken cancellationToken)
{
// Do something before the handler is invoked
var response = await next(request, cancellationToken);
// Do something after the handler is invoked
return response;
}
}
As such, a middleware can modify or replace the request or response, or even short-circuit the pipeline by not calling next.
Middleware can come in two variants: Open or closed generics. Closed generics are defined for a specific request and response type, while open generics can be used for any request and response type.
public class MyMiddleware : IMiddleware<MyQuery, MyResponse> { ... } // Closed generic
public class MyOpenGenericMiddleware<TRequest, TResponse> : IMiddleware<TRequest, TResponse> { ... } // Open generic
Open middleware can be registered on the handler in three different ways:
[Middleware(typeof(MyOpenGenericMiddleware<,>))]- Registers the open generic middleware for the specific request and response type of the handler.[Middleware<MyOpenGenericMiddleware<MyRequest, MyResponse>>]- Same as above, but using a generic type parameter.[Middleware<MyOpenGenericMiddleware<_, _>>]- Same as above, but using the special_-type as a placeholder. The source generator will replace the_with the request and response type of the handler.
Closed middleware can only be registered using the first two methods.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|