// Copyright (c) The Geekeey Authors // SPDX-License-Identifier: EUPL-1.2 using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace Geekeey.Request.Dispatcher; internal abstract class ScalarRequestInvoker { public abstract Task HandleAsync(object request, IServiceProvider serviceProvider, CancellationToken cancellationToken); } internal abstract class ScalarRequestInvoker : ScalarRequestInvoker { public abstract Task HandleAsync(IScalarRequest request, IServiceProvider serviceProvider, CancellationToken cancellationToken); } internal sealed class ScalarRequestInvoker : ScalarRequestInvoker where TRequest : IScalarRequest { public override async Task HandleAsync(object request, IServiceProvider serviceProvider, CancellationToken cancellationToken) { return await HandleAsync((IScalarRequest)request, serviceProvider, cancellationToken).ConfigureAwait(false); } public override Task HandleAsync(IScalarRequest request, IServiceProvider serviceProvider, CancellationToken cancellationToken) { var options = serviceProvider.GetRequiredService>().Value; var pipeline = options.GetRequestBehaviors>(serviceProvider) .Reverse() .Aggregate((ScalarHandlerDelegate)Head, Chain); return pipeline(request, cancellationToken); static ScalarHandlerDelegate Chain(ScalarHandlerDelegate next, IScalarRequestBehavior filter) { return (req, ct) => filter.HandleAsync((TRequest)req, next, ct); } Task Head(IScalarRequest r, CancellationToken ct) { return options.GetRequestHandlers>(serviceProvider).First().HandleAsync((TRequest)r, ct); } } }