dispatcher

This commit is contained in:
2026-02-05 19:21:25 +01:00
parent 01f25fb093
commit 9c75216bea
3 changed files with 94 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Abstract.Query;
namespace AipsCore.Application.Abstract;
public interface IDispatcher
{
Task Execute(ICommand command, CancellationToken cancellationToken = default);
Task<TResult> Execute<TResult>(ICommand<TResult> command, CancellationToken cancellationToken = default);
Task<TResult> Execute<TResult>(IQuery<TResult> query, CancellationToken cancellationToken = default);
}

View File

@@ -0,0 +1,11 @@
using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Abstract.Query;
namespace AipsCore.Application.Common.Dispatcher;
public class DispatchException : Exception
{
public DispatchException(object commandQuery)
: base($"Error while dispatching '{commandQuery.GetType().Name}'")
{ }
}

View File

@@ -0,0 +1,71 @@
using AipsCore.Application.Abstract;
using AipsCore.Application.Abstract.Command;
using AipsCore.Application.Abstract.Query;
using Microsoft.Extensions.DependencyInjection;
namespace AipsCore.Application.Common.Dispatcher;
public sealed class Dispatcher : IDispatcher
{
private readonly IServiceProvider _serviceProvider;
public Dispatcher(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
#region Execute
public async Task Execute(ICommand command, CancellationToken cancellationToken = default)
{
var handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType());
await this.Handle(handlerType, command, cancellationToken);
}
public async Task<TResult> Execute<TResult>(ICommand<TResult> command, CancellationToken cancellationToken = default)
{
var handlerType = typeof(ICommandHandler<,>).MakeGenericType(command.GetType(), typeof(TResult));
return await this.HandleWithResult<TResult>(handlerType, command, cancellationToken);
}
public async Task<TResult> Execute<TResult>(IQuery<TResult> query, CancellationToken cancellationToken = default)
{
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
return await this.HandleWithResult<TResult>(handlerType, query, cancellationToken);
}
#endregion
#region Handle
private async Task Handle(Type handlerType, object commandOrQuery, CancellationToken cancellationToken = default)
{
dynamic handler = this.ResolveHandler(handlerType, commandOrQuery);
await handler.Handle((dynamic)commandOrQuery, cancellationToken);
}
private async Task<TResult> HandleWithResult<TResult>(Type handlerType, object commandOrQuery, CancellationToken cancellationToken = default)
{
dynamic handler = this.ResolveHandler(handlerType, commandOrQuery);
return await handler.Handle((dynamic)commandOrQuery, cancellationToken);
}
#endregion
private dynamic ResolveHandler(Type handlerType, object commandOrQuery)
{
dynamic? handler = _serviceProvider.GetService(handlerType);
if (handler is null)
{
throw new DispatchException(commandOrQuery);
}
return handler;
}
}