Example #1
0
        /// <summary>Returns the desired method to call and it's parameters types, as specified in the payload parameter.</summary>
        /// <param name="payload">The payload specifying the parameters and the method that wants to be called. </param>
        /// <param name="bindingFlags">The flags that will be used for trying to get the desired method through reflection.</param>
        /// <param name="settingItem">The object from which obtain the method to be called. </param>
        /// <returns>A SettingInfo object with the method to be called and an array with it's type parameters". </returns>
        public static SetInfo GetDesiredMethod(Payload payload, BindingFlags bindingFlags, SettingItem settingItem)
        {
            // Get the parameter types to get the right overload.
            Type[] paramTypes = Type.EmptyTypes;
            if (payload.Parameters != null)
            {
                paramTypes = payload.Parameters.Select(p => p.GetType()).ToArray();
            }

            MethodInfo method =
                settingItem.GetType().GetMethod(payload.Method, bindingFlags, null, paramTypes, null);

            if (method == null)
            {
                // Method can't be found matching the parameter types, get any method with the same name
                // and let .Invoke worry about the parameters.
                try
                {
                    method = settingItem.GetType().GetMethod(payload.Method, bindingFlags);
                }
                catch (AmbiguousMatchException)
                {
                    method = null;
                }

                if (method == null)
                {
                    throw new SettingFailedException("Unknown method " + payload.Method);
                }
            }

            if (!method.IsExposed())
            {
                // Only use those with the "Exposed" attribute.
                throw new SettingFailedException("Not an exposed method " + payload.Method);
            }

            return(new SetInfo(method, paramTypes));
        }
Example #2
0
        /// <summary>
        /// Applies a payload, by invoking the method identified in <c>payload</c>.
        /// </summary>
        /// <param name="payload">The payload.</param>
        /// <returns>The result.</returns>
        public static Result Apply(Payload payload)
        {
            Result result = new Result(payload);

            try
            {
                if (string.IsNullOrEmpty(payload.SettingId))
                {
                    throw new SettingFailedException("settingID is required.");
                }

                if (string.IsNullOrEmpty(payload.Method))
                {
                    throw new SettingFailedException("method is required.");
                }

                SettingItem settingItem;

                // Cache the instance, incase it's re-used.
                if (!settingCache.TryGetValue(payload.SettingId, out settingItem))
                {
                    settingItem = new SettingItem(payload.SettingId, SettingHandler.DryRun);
                    settingCache[payload.SettingId] = settingItem;
                }

                payload.SettingItem = settingItem;

                // Get the parameter types to get the right overload.
                Type[] paramTypes = Type.EmptyTypes;
                if (payload.Parameters != null)
                {
                    paramTypes = payload.Parameters.Select(p => p.GetType()).ToArray();
                }

                BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase;
                MethodInfo   method       =
                    settingItem.GetType().GetMethod(payload.Method, bindingFlags, null, paramTypes, null);

                if (method == null)
                {
                    // Method can't be found matching the parameter types, get any method with the same name
                    // and let .Invoke worry about the parameters.
                    try
                    {
                        method = settingItem.GetType().GetMethod(payload.Method, bindingFlags);
                    }
                    catch (AmbiguousMatchException)
                    {
                        method = null;
                    }

                    if (method == null)
                    {
                        throw new SettingFailedException("Unknown method " + payload.Method);
                    }
                }

                if (!method.IsExposed())
                {
                    // Only use those with the "Exposed" attribute.
                    throw new SettingFailedException("Not an exposed method " + payload.Method);
                }

                try
                {
                    result.ReturnValue = method.Invoke(settingItem, payload.Parameters);
                    if (!(payload.Async ?? true))
                    {
                        settingItem.WaitForCompletion(5);
                    }
                }
                catch (Exception e)
                {
                    // Catching general exceptions is ok with .NET 4 because corrupted state exceptions aren't caught.
                    throw new SettingFailedException(null, e.InnerException ?? e);
                }
            }
            catch (SettingFailedException e)
            {
                result.IsError      = true;
                result.ErrorMessage = e.Message;
            }

            return(result);
        }