예제 #1
0
        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);
        }
예제 #2
0
        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();
                }
            }
        }
예제 #3
0
        private static void Rethrow(RequestExecutedContext context)
        {
            if (context == null)
            {
                return;
            }

            if (context.ExceptionHandled)
            {
                return;
            }

            context.ExceptionDispatchInfo?.Throw();

            if (context.Exception != null)
            {
                throw context.Exception;
            }
        }