예제 #1
0
        private static NotificationAsyncHandler BuildAsyncHandler(
            Type targetType, Type invokePayloadType, MethodInfo method, FilterChain filterChain)
        {
            var isAsyncMethod = method.ReturnType.Name.StartsWith("Task");
            var handler       = isAsyncMethod
                ? RequestHandlerAsyncBuilder.Build(targetType, invokePayloadType, null, method)
                : RequestHandlerSyncToAsyncBuilder.Build(targetType, invokePayloadType, null, method);

            // TODO: Optimize this function when without async filter
            return(async delegate(object self, NotificationMessage notification)
            {
                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, notification);
                    }
                }

                // Call PreFilters

                var handled = false;
                if (filterChain.PreFilterAccessors.Length > 0)
                {
                    var context = new PreNotificationFilterContext
                    {
                        Actor = self,
                        Notification = notification
                    };
                    foreach (var filterAccessor in filterChain.PreFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        var preFilter = filter as IPreNotificationFilter;
                        if (preFilter != null)
                        {
                            preFilter.OnPreNotification(context);
                        }
                        else
                        {
                            await((IPreNotificationAsyncFilter)filter).OnPreNotificationAsync(context);
                        }
                    }
                    handled = context.Handled;
                }

                // Call Handler

                if (handled == false)
                {
                    await handler(self, notification.InvokePayload);
                }

                // Call PostFilters

                if (filterChain.PostFilterAccessors.Length > 0)
                {
                    var context = new PostNotificationFilterContext
                    {
                        Actor = self,
                        Notification = notification,
                        Intercepted = handled
                    };
                    foreach (var filterAccessor in filterChain.PostFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        var postFilter = filter as IPostNotificationFilter;
                        if (postFilter != null)
                        {
                            postFilter.OnPostNotification(context);
                        }
                        else
                        {
                            await((IPostNotificationAsyncFilter)filter).OnPostNotificationAsync(context);
                        }
                    }
                }
            });
        }
예제 #2
0
        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;
            });
        }