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 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; }); }