Exemplo n.º 1
0
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            Delegate              outTransformer;
            MethodInfo            method;
            Delegate              interceptor;
            Tuple <int, Delegate> inTransformer;

            try
            {
                var typeArgs            = binder.GetTypeArguments();
                var hasTypeArgs         = typeArgs != null && typeArgs.Count > 0;
                var methodSelectorTuple = Tuple.Create(binder.Name, hasTypeArgs, args.Length);
                var selectorTuple       = Tuple.Create(binder.Name, hasTypeArgs);

                method         = _publicMethods[methodSelectorTuple];
                outTransformer = _outTransformers.ContainsKey(selectorTuple) ? _outTransformers[selectorTuple] : _identity;
                interceptor    = _interceptors.ContainsKey(selectorTuple) ? _interceptors[selectorTuple] : null;
                inTransformer  = _inTransformers.ContainsKey(binder.Name) ? _inTransformers[binder.Name] : null;

                if (hasTypeArgs)
                {
                    method = method.MakeGenericMethod(typeArgs.ToArray());
                }
            }
            catch
            {
                result = null;
                return(false);
            }
            try
            {
                if (inTransformer != null)
                {
                    args[inTransformer.Item1] = inTransformer.Item2.FastDynamicInvoke(args[inTransformer.Item1]);
                }

                object partialResult;
                if (interceptor != null)
                {
                    Func <object, object[], object>         meth  = method.Invoke;
                    Func <object, Func <object[], object> > curry = Impromptu.Curry(meth);
                    var curriedMethod = curry(_wrappedObject);
                    partialResult = interceptor.FastDynamicInvoke(new object[] { curriedMethod, args });
                }
                else
                {
                    partialResult = method.Invoke(_wrappedObject, args);
                }

                result = outTransformer.FastDynamicInvoke(partialResult);
            }
            catch (TargetInvocationException e)
            {
                throw e.InnerException;
            }
            return(true);
        }