Exemple #1
0
        /// <summary>
        /// <see cref="DynamicObject.TryInvokeMember(InvokeMemberBinder, object[], out object)"/>
        /// </summary>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            if (_verbs.Contains(binder.Name)) // the method name is one of our http verbs - invoke as such
            {
                var unnamedArgs = binder.GetUnnamedArgs(args);

                // filter our sentinal types out of the unnamed args to be passed on the request
                var requestArgs = unnamedArgs.Where(arg => !arg.IsOfType(_reservedTypes));

                // these are the objects that can be passed as unnamed args that we use intenrally and do not pass to the request
                var cancelToken           = unnamedArgs.OfType <CancellationToken>().DefaultIfEmpty(CancellationToken.None).First();
                var serializationSettings = unnamedArgs.OfType <JsonSerializerSettings>().FirstOrNewInstance();

#if EXPERIMENTAL_GENERICS
                // dig the generic type argument out of the binder
                var returnType = binder.GetGenericTypeArguments().FirstOrDefault(); // evil exists within that method
#else
                var returnType = unnamedArgs.OfType <Type>().FirstOrDefault();
#endif
                // if no return type argument provided there is no need for late bound method dispatch
                if (returnType == null)
                {
                    // no return type argument so return result deserialized as dynamic
                    // parse out the details of the invocation and have the derived class create a Task
                    result = CreateVerbAsyncTask <dynamic>(binder.Name, requestArgs, binder.GetNamedArgs(args), cancelToken, serializationSettings);
                }
                else
                {
                    // we got a type argument (like this if experimental: client.get<SomeType>(); or like this normally: client.get(typeof(SomeType)); )
                    // make and invoke the generic implementaiton of the CreateVerbAsyncTask method
                    var methodInfo = this.GetType().GetTypeInfo().GetDeclaredMethod("CreateVerbAsyncTask");
                    var method     = methodInfo.MakeGenericMethod(returnType);
                    result = method.Invoke(this, new object[] { binder.Name, requestArgs, binder.GetNamedArgs(args), cancelToken, serializationSettings });
                }
            }
            else // otherwise the method is yet another uri segment
            {
                if (args.Length != 1)
                {
                    throw new InvalidOperationException("The segment escape sequence must have exactly 1 unnamed parameter");
                }

                // this is for when we escape a url segment by passing it as an argument to a method invocation
                // example: proxy.segment1("escaped")
                // here we create two new dynamic objects, 1 for "segment1" which is the method name
                // and then we create one for the escaped segment passed as an argument - "escaped" in the example
                var tmp = CreateProxyNode(this, binder.Name);
                result = CreateProxyNode(tmp, args[0].ToString());
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// <see cref="System.Dynamic.DynamicObject.TryInvokeMember(InvokeMemberBinder, object[], out object)"/>
        /// </summary>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            Debug.Assert(binder != null);
            Debug.Assert(args != null);

            if (binder.IsVerb())
            {
                // parse out the details of the invocation and have the derived class create a Task
                result = CreateVerbAsyncTask(binder.Name, binder.GetUnnamedArgs(args), binder.GetNamedArgs(args));
            }
            else
            {
                if (args.Length != 1)
                {
                    throw new InvalidOperationException("The segment escape sequence must have exactly 1 unnamed parameter");
                }

                // this is for when we escape a url segment by passing it as an argument to a method invocation
                // example: proxy.segment1("escaped")
                // here we create two new dynamic objects, 1 for "segment1" which is the method name
                // and then we create one for the escaped segment passed as an argument - "escaped" in the example
                var tmp = CreateProxyNode(this, binder.Name);
                result = CreateProxyNode(tmp, args[0].ToString());
            }

            return(true);
        }