Ejemplo n.º 1
0
        private static MessageAsyncHandler BuildGenericAsyncHandler(
            Type targetType, Type messageType, MethodInfo method, FilterChain filterChain)
        {
            var argTypes      = messageType.GetGenericArguments();
            var genericMethod = method.MakeGenericMethod(argTypes.Skip(argTypes.Length - method.GetGenericArguments().Length).ToArray());

            return(BuildAsyncHandler(targetType, messageType, genericMethod, filterChain));
        }
Ejemplo n.º 2
0
        private static NotificationAsyncHandler BuildGenericAsyncHandler(
            Type targetType, Type invokePayloadType, MethodInfo method, FilterChain filterChain)
        {
            var argTypes      = invokePayloadType.GetGenericArguments();
            var genericMethod = method.MakeGenericMethod(argTypes.Skip(argTypes.Length - method.GetGenericArguments().Length).ToArray());

            return(BuildAsyncHandler(targetType, invokePayloadType, genericMethod, filterChain));
        }
Ejemplo n.º 3
0
        private void AddHandler(MethodInfo method, Type messageType, FilterChain filterChain, bool isSyncHandler, bool isReentrant)
        {
            if (method.IsGenericMethod == false)
            {
                if (isSyncHandler)
                {
                    var item = new MessageHandlerItem
                    {
                        IsReentrant = isReentrant,
                        Handler     = BuildHandler(_type, messageType, method, filterChain)
                    };
                    _table.Add(messageType, item);
                }
                else
                {
                    var item = new MessageHandlerItem
                    {
                        IsReentrant  = isReentrant,
                        AsyncHandler = BuildAsyncHandler(_type, messageType, method, filterChain)
                    };
                    _table.Add(messageType, item);
                }
            }
            else
            {
                // because a generic method needs parameter types to construct handler
                // so factory method is built to generate the handler when paramter types are ready

                var defType = messageType.GetGenericTypeDefinition();

                if (isSyncHandler)
                {
                    _table.Add(defType, new MessageHandlerItem
                    {
                        IsReentrant           = isReentrant,
                        IsGeneric             = true,
                        GenericHandlerBuilder = t => new MessageHandlerItem
                        {
                            IsReentrant = isReentrant,
                            Handler     = BuildGenericHandler(_type, t, method, filterChain)
                        }
                    });
                }
                else
                {
                    _table.Add(defType, new MessageHandlerItem
                    {
                        IsReentrant           = isReentrant,
                        IsGeneric             = true,
                        GenericHandlerBuilder = t => new MessageHandlerItem
                        {
                            IsReentrant  = isReentrant,
                            AsyncHandler = BuildGenericAsyncHandler(_type, t, method, filterChain)
                        }
                    });
                }
            }
        }
        private void AddHandler(MethodInfo method, Type messageType, FilterChain filterChain, bool isSyncHandler, bool isReentrant)
        {
            if (method.IsGenericMethod == false)
            {
                if (isSyncHandler)
                {
                    var item = new MessageHandlerItem
                    {
                        IsReentrant = isReentrant,
                        Handler = BuildHandler(_type, messageType, method, filterChain)
                    };
                    _table.Add(messageType, item);
                }
                else
                {
                    var item = new MessageHandlerItem
                    {
                        IsReentrant = isReentrant,
                        AsyncHandler = BuildAsyncHandler(_type, messageType, method, filterChain)
                    };
                    _table.Add(messageType, item);
                }
            }
            else
            {
                // because a generic method needs parameter types to construct handler
                // so factory method is built to generate the handler when paramter types are ready

                var defType = messageType.GetGenericTypeDefinition();

                if (isSyncHandler)
                {
                    _table.Add(defType, new MessageHandlerItem
                    {
                        IsReentrant = isReentrant,
                        IsGeneric = true,
                        GenericHandlerBuilder = t => new MessageHandlerItem
                        {
                            IsReentrant = isReentrant,
                            Handler = BuildGenericHandler(_type, t, method, filterChain)
                        }
                    });
                }
                else
                {
                    _table.Add(defType, new MessageHandlerItem
                    {
                        IsReentrant = isReentrant,
                        IsGeneric = true,
                        GenericHandlerBuilder = t => new MessageHandlerItem
                        {
                            IsReentrant = isReentrant,
                            AsyncHandler = BuildGenericAsyncHandler(_type, t, method, filterChain)
                        }
                    });
                }
            }
        }
        private static MessageHandler BuildHandler(
            Type targetType, Type messageType, MethodInfo method, FilterChain filterChain)
        {
            var handler = MessageHandlerFuncBuilder.Build(targetType, method);
            if (filterChain.Empty)
                return handler;

            return (self, message) =>
            {
                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, message);
                    }
                }

                // Call PreFilters

                var handled = false;
                if (filterChain.PreFilterAccessors.Length > 0)
                {
                    var context = new PreMessageFilterContext
                    {
                        Actor = self,
                        Message = message
                    };
                    foreach (var filterAccessor in filterChain.PreFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        ((IPreMessageFilter)filter).OnPreMessage(context);
                    }
                    handled = context.Handled;
                }

                // Call Handler

                if (handled == false)
                    handler(self, message);

                // Call PostFilters

                if (filterChain.PostFilterAccessors.Length > 0)
                {
                    var context = new PostMessageFilterContext
                    {
                        Actor = self,
                        Message = message,
                        Intercepted = handled
                    };
                    foreach (var filterAccessor in filterChain.PostFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        ((IPostMessageFilter)filter).OnPostMessage(context);
                    }
                }
            };
        }
Ejemplo n.º 6
0
        private static RequestHandler BuildGenericHandler(
            Type targetType, Type invokePayloadType, Type returnPayloadType, MethodInfo method, FilterChain filterChain)
        {
            var argTypes = invokePayloadType.GetGenericArguments();
            var genericReturnPayloadType = returnPayloadType?.MakeGenericType(argTypes);
            var genericMethod            = method.MakeGenericMethod(argTypes.Skip(argTypes.Length - method.GetGenericArguments().Length).ToArray());

            return(BuildHandler(targetType, invokePayloadType, genericReturnPayloadType, genericMethod, filterChain));
        }
Ejemplo n.º 7
0
        private static MessageAsyncHandler BuildAsyncHandler(
            Type targetType, Type messageType, MethodInfo method, FilterChain filterChain)
        {
            var isAsyncMethod = method.ReturnType.Name.StartsWith("Task");
            var handler       = isAsyncMethod
                ? MessageHandlerAsyncBuilder.Build(targetType, method)
                : MessageHandlerSyncToAsyncBuilder.Build(targetType, method);

            if (filterChain.Empty)
            {
                return(handler);
            }

            return(async(self, message) =>
            {
                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, message);
                    }
                }

                // Call PreFilters

                var handled = false;
                if (filterChain.PreFilterAccessors.Length > 0)
                {
                    var context = new PreMessageFilterContext
                    {
                        Actor = self,
                        Message = message
                    };
                    foreach (var filterAccessor in filterChain.PreFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        var preFilter = filter as IPreMessageFilter;
                        if (preFilter != null)
                        {
                            preFilter.OnPreMessage(context);
                        }
                        else
                        {
                            await((IPreMessageAsyncFilter)filter).OnPreMessageAsync(context);
                        }
                    }
                    handled = context.Handled;
                }

                // Call Handler

                if (handled == false)
                {
                    await handler(self, message);
                }

                // Call PostFilters

                if (filterChain.PostFilterAccessors.Length > 0)
                {
                    var context = new PostMessageFilterContext
                    {
                        Actor = self,
                        Message = message,
                        Intercepted = handled
                    };
                    foreach (var filterAccessor in filterChain.PostFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        var postFilter = filter as IPostMessageFilter;
                        if (postFilter != null)
                        {
                            postFilter.OnPostMessage(context);
                        }
                        else
                        {
                            await((IPostMessageAsyncFilter)filter).OnPostMessageAsync(context);
                        }
                    }
                }
            });
        }
Ejemplo n.º 8
0
        private static MessageHandler BuildHandler(
            Type targetType, Type messageType, MethodInfo method, FilterChain filterChain)
        {
            var handler = MessageHandlerFuncBuilder.Build(targetType, method);

            if (filterChain.Empty)
            {
                return(handler);
            }

            return((self, message) =>
            {
                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, message);
                    }
                }

                // Call PreFilters

                var handled = false;
                if (filterChain.PreFilterAccessors.Length > 0)
                {
                    var context = new PreMessageFilterContext
                    {
                        Actor = self,
                        Message = message
                    };
                    foreach (var filterAccessor in filterChain.PreFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        ((IPreMessageFilter)filter).OnPreMessage(context);
                    }
                    handled = context.Handled;
                }

                // Call Handler

                if (handled == false)
                {
                    handler(self, message);
                }

                // Call PostFilters

                if (filterChain.PostFilterAccessors.Length > 0)
                {
                    var context = new PostMessageFilterContext
                    {
                        Actor = self,
                        Message = message,
                        Intercepted = handled
                    };
                    foreach (var filterAccessor in filterChain.PostFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        ((IPostMessageFilter)filter).OnPostMessage(context);
                    }
                }
            });
        }
 private static MessageAsyncHandler BuildGenericAsyncHandler(
     Type targetType, Type messageType, MethodInfo method, FilterChain filterChain)
 {
     var argTypes = messageType.GetGenericArguments();
     var genericMethod = method.MakeGenericMethod(argTypes.Skip(argTypes.Length - method.GetGenericArguments().Length).ToArray());
     return BuildAsyncHandler(targetType, messageType, genericMethod, filterChain);
 }
        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);
                    }
                }
            };
        }
Ejemplo n.º 11
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;
            });
        }
Ejemplo n.º 12
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);
                        }
                    }
                }
            });
        }
        private void AddHandler(Type interfaceType, MethodInfo method, Type invokePayloadType, FilterChain filterChain, bool isSyncHandler, bool isReentrant)
        {
            if (method.IsGenericMethod == false)
            {
                if (isSyncHandler)
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType = interfaceType,
                        IsReentrant = isReentrant,
                        Handler = BuildHandler(_type, invokePayloadType, method, filterChain)
                    });
                }
                else
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType = interfaceType,
                        IsReentrant = isReentrant,
                        AsyncHandler = BuildAsyncHandler(_type, invokePayloadType, method, filterChain)
                    });
                }
            }
            else
            {
                // because a generic method needs parameter types to construct handler
                // so factory method is built to generate the handler when paramter types are ready

                if (isSyncHandler)
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType = interfaceType,
                        IsReentrant = isReentrant,
                        IsGeneric = true,
                        GenericHandlerBuilder = t => new NotificationHandlerItem
                        {
                            InterfaceType = interfaceType,
                            IsReentrant = isReentrant,
                            Handler = BuildGenericHandler(_type, t, method, filterChain)
                        }
                    });
                }
                else
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType = interfaceType,
                        IsReentrant = isReentrant,
                        IsGeneric = true,
                        GenericHandlerBuilder = t => new NotificationHandlerItem
                        {
                            InterfaceType = interfaceType,
                            IsReentrant = isReentrant,
                            AsyncHandler = BuildGenericAsyncHandler(_type, t, method, filterChain)
                        }
                    });
                }
            }
        }
Ejemplo n.º 14
0
        private static NotificationHandler BuildHandler(
            Type targetType, Type invokePayloadType, MethodInfo method, FilterChain filterChain)
        {
            var handler = RequestHandlerFuncBuilder.Build(targetType, invokePayloadType, null, method);

            return(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);
                        ((IPreNotificationFilter)filter).OnPreNotification(context);
                    }
                    handled = context.Handled;
                }

                // Call Handler

                if (handled == false)
                {
                    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);
                        ((IPostNotificationFilter)filter).OnPostNotification(context);
                    }
                }
            });
        }
Ejemplo n.º 15
0
        private void AddHandler(Type interfaceType, MethodInfo method, Type invokePayloadType, FilterChain filterChain, bool isSyncHandler, bool isReentrant)
        {
            if (method.IsGenericMethod == false)
            {
                if (isSyncHandler)
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType = interfaceType,
                        IsReentrant   = isReentrant,
                        Handler       = BuildHandler(_type, invokePayloadType, method, filterChain)
                    });
                }
                else
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType = interfaceType,
                        IsReentrant   = isReentrant,
                        AsyncHandler  = BuildAsyncHandler(_type, invokePayloadType, method, filterChain)
                    });
                }
            }
            else
            {
                // because a generic method needs parameter types to construct handler
                // so factory method is built to generate the handler when paramter types are ready

                if (isSyncHandler)
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType         = interfaceType,
                        IsReentrant           = isReentrant,
                        IsGeneric             = true,
                        GenericHandlerBuilder = t => new NotificationHandlerItem
                        {
                            InterfaceType = interfaceType,
                            IsReentrant   = isReentrant,
                            Handler       = BuildGenericHandler(_type, t, method, filterChain)
                        }
                    });
                }
                else
                {
                    _table.Add(invokePayloadType, new NotificationHandlerItem
                    {
                        InterfaceType         = interfaceType,
                        IsReentrant           = isReentrant,
                        IsGeneric             = true,
                        GenericHandlerBuilder = t => new NotificationHandlerItem
                        {
                            InterfaceType = interfaceType,
                            IsReentrant   = isReentrant,
                            AsyncHandler  = BuildGenericAsyncHandler(_type, t, method, filterChain)
                        }
                    });
                }
            }
        }
 private static RequestHandler BuildGenericHandler(
     Type targetType, Type invokePayloadType, Type returnPayloadType, MethodInfo method, FilterChain filterChain)
 {
     var argTypes = invokePayloadType.GetGenericArguments();
     var genericReturnPayloadType = returnPayloadType?.MakeGenericType(argTypes);
     var genericMethod = method.MakeGenericMethod(argTypes.Skip(argTypes.Length - method.GetGenericArguments().Length).ToArray());
     return BuildHandler(targetType, invokePayloadType, genericReturnPayloadType, genericMethod, filterChain);
 }
        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;
            };
        }
        private static RequestHandler BuildHandler(
            Type targetType, Type invokePayloadType, Type returnPayloadType, MethodInfo method, FilterChain filterChain)
        {
            var handler = RequestHandlerFuncBuilder.Build(targetType, invokePayloadType, returnPayloadType, method);

            return 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);
                            ((IPreRequestFilter)filter).OnPreRequest(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 = 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);
                            ((IPostRequestFilter)filter).OnPostRequest(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;
            };
        }
        private static NotificationHandler BuildHandler(
            Type targetType, Type invokePayloadType, MethodInfo method, FilterChain filterChain)
        {
            var handler = RequestHandlerFuncBuilder.Build(targetType, invokePayloadType, null, method);

            return 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);
                        ((IPreNotificationFilter)filter).OnPreNotification(context);
                    }
                    handled = context.Handled;
                }

                // Call Handler

                if (handled == false)
                    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);
                        ((IPostNotificationFilter)filter).OnPostNotification(context);
                    }
                }
            };
        }
        private static MessageAsyncHandler BuildAsyncHandler(
            Type targetType, Type messageType, MethodInfo method, FilterChain filterChain)
        {
            var isAsyncMethod = method.ReturnType.Name.StartsWith("Task");
            var handler = isAsyncMethod
                ? MessageHandlerAsyncBuilder.Build(targetType, method)
                : MessageHandlerSyncToAsyncBuilder.Build(targetType, method);
            if (filterChain.Empty)
                return handler;

            return async (self, message) =>
            {
                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, message);
                    }
                }

                // Call PreFilters

                var handled = false;
                if (filterChain.PreFilterAccessors.Length > 0)
                {
                    var context = new PreMessageFilterContext
                    {
                        Actor = self,
                        Message = message
                    };
                    foreach (var filterAccessor in filterChain.PreFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        var preFilter = filter as IPreMessageFilter;
                        if (preFilter != null)
                            preFilter.OnPreMessage(context);
                        else
                            await ((IPreMessageAsyncFilter)filter).OnPreMessageAsync(context);
                    }
                    handled = context.Handled;
                }

                // Call Handler

                if (handled == false)
                    await handler(self, message);

                // Call PostFilters

                if (filterChain.PostFilterAccessors.Length > 0)
                {
                    var context = new PostMessageFilterContext
                    {
                        Actor = self,
                        Message = message,
                        Intercepted = handled
                    };
                    foreach (var filterAccessor in filterChain.PostFilterAccessors)
                    {
                        var filter = filterAccessor(filterPerInstanceProvider, filterPerRequests);
                        var postFilter = filter as IPostMessageFilter;
                        if (postFilter != null)
                            postFilter.OnPostMessage(context);
                        else
                            await ((IPostMessageAsyncFilter)filter).OnPostMessageAsync(context);
                    }
                }
            };
        }
 private static NotificationAsyncHandler BuildGenericAsyncHandler(
     Type targetType, Type invokePayloadType, MethodInfo method, FilterChain filterChain)
 {
     var argTypes = invokePayloadType.GetGenericArguments();
     var genericMethod = method.MakeGenericMethod(argTypes.Skip(argTypes.Length - method.GetGenericArguments().Length).ToArray());
     return BuildAsyncHandler(targetType, invokePayloadType, genericMethod, filterChain);
 }
Ejemplo n.º 22
0
        private static RequestHandler BuildHandler(
            Type targetType, Type invokePayloadType, Type returnPayloadType, MethodInfo method, FilterChain filterChain)
        {
            var handler = RequestHandlerFuncBuilder.Build(targetType, invokePayloadType, returnPayloadType, method);

            return(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);
                            ((IPreRequestFilter)filter).OnPreRequest(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 = 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);
                            ((IPostRequestFilter)filter).OnPostRequest(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;
            });
        }