/// <summary> /// Builds <see cref="HandlerDescriptor"/> for <paramref name="handler"/> and its <paramref name="argumentType"/> (wrapper or unwrapper). /// </summary> /// <param name="handler">The handler to build descriptor for.</param> /// <param name="argumentType">The argument type (possibly wrapped in envelope or context).</param> /// <returns>The instance of the handler descriptor.</returns> public HandlerDescriptor Get(object handler, Type argumentType) { Ensure.NotNull(handler, "handler"); Type handlerType = handler.GetType(); string handlerIdentifier = FindIdentifier(handlerType); MethodInfo method = handlerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .FirstOrDefault(m => m.Name.EndsWith(methodName) && m.GetParameters()[0].ParameterType == argumentType); Func <object, object, Action <Exception>, Task> handlerAction = (h, p, additionalExceptionDecorator) => { try { Task result = (Task)method.Invoke(h, new object[] { p }); result = result.ContinueWith(task => { if (task.IsFaulted) { innerExceptionHandlers.Handle(task.Exception.InnerException); return(Async.CompletedTask); } return(task); }); return(result); } catch (TargetInvocationException e) { if (additionalExceptionDecorator != null) { additionalExceptionDecorator(e.InnerException); } innerExceptionHandlers.Handle(e.InnerException); return(Async.CompletedTask); } catch (Exception e) { if (additionalExceptionDecorator != null) { additionalExceptionDecorator(e); } outerExceptionHandlers.Handle(e); return(Async.CompletedTask); } }; ArgumentDescriptor argument = Get(argumentType); return(new HandlerDescriptor( handlerIdentifier, handler, argument.ArgumentType, handlerAction, argument.IsPlain, argument.IsEnvelope, argument.IsContext )); }