diff --git a/Arbitrer/pipelines/ArbitrerPipeline.cs b/Arbitrer/pipelines/ArbitrerPipeline.cs index 429cf2e..73355fd 100644 --- a/Arbitrer/pipelines/ArbitrerPipeline.cs +++ b/Arbitrer/pipelines/ArbitrerPipeline.cs @@ -1,5 +1,6 @@ using System; using System.Linq.Expressions; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using MediatR; @@ -13,7 +14,9 @@ namespace Arbitrer.Pipelines /// /// The type of the request. /// The type of the response. - public class ArbitrerPipeline : IPipelineBehavior //where TRequest : notnull + public class ArbitrerPipeline : IPipelineBehavior + where TRequest : class, IBaseRequest + //where TRequest : notnull { private readonly IArbitrer arbitrer; private readonly ILogger _logger; @@ -24,45 +27,7 @@ public ArbitrerPipeline(IArbitrer arbitrer, ILogger logger) _logger = logger; } - // Implementation for legacy version for .netstandard 2.0 compatibility - /// - /// Handles a request asynchronously. - /// - /// The type of the request. - /// The type of the response. - /// The request to be handled. - /// The cancellation token. - /// The delegate to invoke the next handler in the pipeline. - /// A task representing the asynchronous handling of the request. - /// Thrown when the handler location is invalid. - public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next) - { - object req = request; - string queueName = null; - - if (typeof(IExplicitQueue).IsAssignableFrom(request.GetType())) - { - queueName = ((IExplicitQueue)request).QueueName; - req = ((IExplicitQueue)request).MessageObject; - } - - try - { - switch (arbitrer.GetLocation(req.GetType())) - { - case HandlerLocation.Local: return await next().ConfigureAwait(false); - case HandlerLocation.Remote: return await arbitrer.InvokeRemoteHandler(request, queueName); - default: throw new InvalidHandlerException(); - } - } - catch (Exception ex) - { - _logger.LogError(ex, ex.Message); - throw; - } - } - // Implementation for version > 11 /// /// Handles the request by invoking the appropriate handler based on the location of the request. /// @@ -74,21 +39,27 @@ public async Task Handle(TRequest request, CancellationToken cancella /// The response data. public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { - object req = request; - string queueName = null; - if (typeof(IExplicitQueue).IsAssignableFrom(request.GetType())) { - queueName = ((IExplicitQueue)request).QueueName; - req = ((IExplicitQueue)request).MessageObject; + var queueName = ((IExplicitQueue)request).QueueName; + var req = ((IExplicitQueue)request).MessageObject; + var type = request.GetType().GetGenericArguments()[0]; + + return ((TResponse)this.GetType().GetMethod(nameof(InvokeHandler), BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(type) + .Invoke(this, new object[] { next, req, queueName })); } + return await InvokeHandler(next, request, null); + } + + private async Task InvokeHandler(RequestHandlerDelegate next, T req, string queueName) + { try { switch (arbitrer.GetLocation(req.GetType())) { case HandlerLocation.Local: return await next().ConfigureAwait(false); - case HandlerLocation.Remote: return await arbitrer.InvokeRemoteHandler(request, queueName); + case HandlerLocation.Remote: return await arbitrer.InvokeRemoteHandler(req, queueName); default: throw new InvalidHandlerException(); } }