avatar
Untitled

Guest 12 13th Mar, 2025

CSHARP 4.32 KB
                                           
                         namespace GainCapital.Execution.DealingManager.Infrastructure.CqrsExtensions
{
    public class CqrsDispatcher : ICqrsDispatcher
    {
        private static readonly ConcurrentDictionary<Type, QueryDispatcherBase> QueryDispatchers = new ConcurrentDictionary<Type, QueryDispatcherBase>();
        private static readonly ConcurrentDictionary<Type, CommandDispatcherBase> CommandDispatchers = new ConcurrentDictionary<Type, CommandDispatcherBase>();

        private readonly IServiceProvider _serviceProvider;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public CqrsDispatcher(IServiceProvider serviceProvider, IHttpContextAccessor httpContextAccessor)
        {
            _serviceProvider = serviceProvider;
            _httpContextAccessor = httpContextAccessor;
        }

        public Task<TResult> DispatchAsync<TResult>(IQuery<TResult> query)
        {
            var queryDispatcher = QueryDispatchers.GetOrAdd(query.GetType(), queryType =>
            {
                var makeGenericType = typeof(QueryDispatcher<,>).MakeGenericType(queryType, typeof(TResult));
                return (QueryDispatcherBase)Activator.CreateInstance(makeGenericType)!;
            });
            var cancellationToken = _httpContextAccessor.HttpContext?.RequestAborted;
            return (Task<TResult>)queryDispatcher.Dispatch(query, _serviceProvider, cancellationToken ?? default);
        }

        public Task<TResult> DispatchAsync<TResult>(ICommand<TResult> command) where TResult : CSharpFunctionalExtensions.IResult
        {
            var commandDispatcher = CommandDispatchers.GetOrAdd(command.GetType(), commandType =>
            {
                var makeGenericType = typeof(CommandDispatcher<,>).MakeGenericType(commandType, typeof(TResult));
                return (CommandDispatcherBase)Activator.CreateInstance(makeGenericType)!;
            });
            var cancellationToken = _httpContextAccessor.HttpContext?.RequestAborted;
            return (Task<TResult>)commandDispatcher.Dispatch(command, _serviceProvider, cancellationToken ?? default);
        }
    }

    internal abstract class QueryDispatcherBase
    {
        public abstract object Dispatch(object query, IServiceProvider serviceProvider, CancellationToken cancellationToken);
    }

    internal class QueryDispatcher<TQuery, TResult> : QueryDispatcherBase where TQuery : IQuery<TResult>
    {
        public override object Dispatch(object query, IServiceProvider serviceProvider, CancellationToken cancellationToken)
        {
            return Dispatch((TQuery)query, serviceProvider, cancellationToken);
        }

        private static async Task<TResult> Dispatch(TQuery query, IServiceProvider serviceProvider, CancellationToken cancellationToken)
        {
            using var serviceScope = serviceProvider.CreateScope();
            var queryHandler = serviceScope.ServiceProvider.GetRequiredService<IQueryHandler<TQuery, TResult>>();
            return await queryHandler.Handle(query, cancellationToken);
        }
    }

    internal abstract class CommandDispatcherBase
    {
        public abstract object Dispatch(object command, IServiceProvider serviceProvider, CancellationToken cancellationToken);
    }

    internal class CommandDispatcher<TCommand, TResult> : CommandDispatcherBase where TCommand : ICommand<TResult> where TResult : CSharpFunctionalExtensions.IResult
    {
        public override object Dispatch(object command, IServiceProvider serviceProvider, CancellationToken cancellationToken)
        {
            return Dispatch((TCommand)command, serviceProvider, cancellationToken);
        }

        private static async Task<TResult> Dispatch(TCommand command, IServiceProvider serviceProvider, CancellationToken cancellationToken)
        {
            using var serviceScope = serviceProvider.CreateScope();
            var queryHandler = serviceScope.ServiceProvider.GetRequiredService<ICommandHandler<TCommand, TResult>>();
            return await queryHandler.HandleAsync(command, cancellationToken);
        }
    }
}
                      
                                       
To share this paste please copy this url and send to your friends
RAW Paste Data
Recent Pastes
Ta strona używa plików cookie w celu usprawnienia i ułatwienia dostępu do serwisu oraz prowadzenia danych statystycznych. Dalsze korzystanie z tej witryny oznacza akceptację tego stanu rzeczy.
Wykorzystywanie plików Cookie
Jak wyłączyć cookies?
ROZUMIEM