private RequestExecutionDelegate GetRequestExecutionDelegate(object[] arguments) { var requestExecutingContext = new RequestExecutingContext(RequestContext, Interceptors, MappingArguments(arguments)); var requestExecutedContext = new RequestExecutedContext(RequestContext, Interceptors); var requestInterceptors = Interceptors .OfType <IAsyncRequestInterceptor>() .ToArray(); IList <Func <RequestExecutionDelegate, RequestExecutionDelegate> > requestExecutions = new List <Func <RequestExecutionDelegate, RequestExecutionDelegate> >(); foreach (var interceptor in requestInterceptors) { requestExecutions.Add(next => { return(async() => { await interceptor.OnRequestExecutionAsync(requestExecutingContext, next); if (requestExecutingContext.Result != null) { requestExecutedContext.Result = requestExecutingContext.Result; } return requestExecutedContext; }); }); } RequestExecutionDelegate requestInvoker = async() => { try { requestExecutedContext.Result = await DoInvokeAsync(); } catch (Exception e) { requestExecutedContext.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(e); } return(requestExecutedContext); }; foreach (var func in requestExecutions.Reverse()) { requestInvoker = func(requestInvoker); } return(requestInvoker); }
public virtual async Task <object> InvokeAsync(object[] arguments) { var requestExecutionDelegate = GetRequestExecutionDelegate(arguments); RequestExecutedContext requestExecutedContext = null; try { await InitializeRequestAsync(RequestContext.GoContext.Request, arguments); requestExecutedContext = await requestExecutionDelegate(); Rethrow(requestExecutedContext); return(requestExecutedContext?.Result); } catch (Exception e) { var exceptionInterceptorContext = new ExceptionInterceptorContext(RequestContext, Interceptors) { ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(e), Result = requestExecutedContext?.Result }; var exceptionInterceptors = Interceptors .OfType <IAsyncExceptionInterceptor>() .Reverse() .ToArray(); foreach (var interceptor in exceptionInterceptors) { await interceptor.OnExceptionAsync(exceptionInterceptorContext); } Rethrow(exceptionInterceptorContext); return(exceptionInterceptorContext.Result); } finally { if (RequestContext.GoContext.RequestServices is IDisposable disposable) { disposable.Dispose(); } } }
private static void Rethrow(RequestExecutedContext context) { if (context == null) { return; } if (context.ExceptionHandled) { return; } context.ExceptionDispatchInfo?.Throw(); if (context.Exception != null) { throw context.Exception; } }