Akka.Interfaced.RequestHandlerBuilder.BuildAsyncHandler C# (CSharp) Method

BuildAsyncHandler() private static method

private static BuildAsyncHandler ( Type targetType, Type invokePayloadType, Type returnPayloadType, MethodInfo method, FilterChain filterChain ) : RequestAsyncHandler
targetType System.Type
invokePayloadType System.Type
returnPayloadType System.Type
method System.Reflection.MethodInfo
filterChain FilterChain
return RequestAsyncHandler
        private static RequestAsyncHandler BuildAsyncHandler(
            Type targetType, Type invokePayloadType, Type returnPayloadType, MethodInfo method, FilterChain filterChain)
        {
            var isAsyncMethod = method.ReturnType.Name.StartsWith("Task");
            var handler = isAsyncMethod
                ? RequestHandlerAsyncBuilder.Build(targetType, invokePayloadType, returnPayloadType, method)
                : RequestHandlerSyncToAsyncBuilder.Build(targetType, invokePayloadType, returnPayloadType, method);

            // TODO: Optimize this function when without async filter
            return async delegate(object self, RequestMessage request, Action<ResponseMessage, Exception> onCompleted)
            {
                var filterPerInstanceProvider = filterChain.PerInstanceFilterExists ? (IFilterPerInstanceProvider)self : null;

                // Create PerRequest filters

                IFilter[] filterPerRequests = null;
                if (filterChain.PerInvokeFilterFactories.Length > 0)
                {
                    filterPerRequests = new IFilter[filterChain.PerInvokeFilterFactories.Length];
                    for (var i = 0; i < filterChain.PerInvokeFilterFactories.Length; i++)
                    {
                        filterPerRequests[i] = filterChain.PerInvokeFilterFactories[i].CreateInstance(self, request);
                    }
                }

                // Call PreFilters

                ResponseMessage response = null;
                Exception exception = null;

                if (filterChain.PreFilterAccessors.Length > 0)
                {
                    var context = new PreRequestFilterContext
                    {
                        Actor = self,
                        Request = request
                    };
                    foreach (var filterAccessor in filterChain.PreFilterAccessors)
                    {
                        try
                        {
                            var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                            var preFilter = filter as IPreRequestFilter;
                            if (preFilter != null)
                                preFilter.OnPreRequest(context);
                            else
                                await ((IPreRequestAsyncFilter)filter).OnPreRequestAsync(context);
                        }
                        catch (Exception e)
                        {
                            context.Exception = e;
                        }
                    }
                    response = context.Response;
                    exception = context.Exception;
                }

                // Call Handler

                var intercepted = response != null || exception != null;
                if (intercepted == false)
                {
                    try
                    {
                        var returnPayload = await handler(self, request.InvokePayload);
                        response = new ResponseMessage
                        {
                            RequestId = request.RequestId,
                            ReturnPayload = returnPayload
                        };
                    }
                    catch (ResponsiveException e)
                    {
                        response = new ResponseMessage
                        {
                            RequestId = request.RequestId,
                            Exception = e.InnerException
                        };
                    }
                    catch (Exception e)
                    {
                        exception = e;
                    }
                }

                // Call PostFilters

                if (filterChain.PostFilterAccessors.Length > 0)
                {
                    var context = new PostRequestFilterContext
                    {
                        Actor = self,
                        Request = request,
                        Response = response,
                        Exception = exception,
                        Intercepted = intercepted
                    };
                    foreach (var filterAccessor in filterChain.PostFilterAccessors)
                    {
                        try
                        {
                            var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                            var postFilter = filter as IPostRequestFilter;
                            if (postFilter != null)
                                postFilter.OnPostRequest(context);
                            else
                                await ((IPostRequestAsyncFilter)filter).OnPostRequestAsync(context);
                        }
                        catch (Exception e)
                        {
                            context.Exception = e;
                        }
                    }
                    response = context.Response;
                    exception = context.Exception;
                }

                // Build response for a thrown exception

                if (exception != null && response == null)
                {
                    response = new ResponseMessage
                    {
                        RequestId = request.RequestId,
                        Exception = new RequestFaultException("", exception)
                    };
                }

                // Callback

                onCompleted?.Invoke(response, exception);

                return response;
            };
        }