Exemple #1
0
    public static void Dispatch(System.Object target, DynamicServerAction dynamicServerAction)
    {
        MethodInfo method = getDispatchMethod(target.GetType(), dynamicServerAction);

        if (method == null)
        {
            throw new InvalidActionException();
        }

        List <string> missingArguments = null;

        System.Reflection.ParameterInfo[] methodParams = method.GetParameters();
        object[] arguments = new object[methodParams.Length];
        if (methodParams.Length == 1 && methodParams[0].ParameterType == typeof(ServerAction))
        {
            ServerAction serverAction = dynamicServerAction.ToObject <ServerAction>();
            serverAction.dynamicServerAction = dynamicServerAction;
            arguments[0] = serverAction;
        }
        else
        {
            for (int i = 0; i < methodParams.Length; i++)
            {
                System.Reflection.ParameterInfo pi = methodParams[i];
                if (dynamicServerAction.ContainsKey(pi.Name))
                {
                    try {
                        arguments[i] = dynamicServerAction.GetValue(pi.Name).ToObject(pi.ParameterType);
                    } catch (ArgumentException ex) {
                        throw new ToObjectArgumentActionException(
                                  parameterName: pi.Name,
                                  parameterType: pi.ParameterType,
                                  parameterValueAsStr: dynamicServerAction.GetValue(pi.Name).ToString(),
                                  ex: ex
                                  );
                    }
                }
                else
                {
                    if (!pi.HasDefaultValue)
                    {
                        if (missingArguments == null)
                        {
                            missingArguments = new List <string>();
                        }
                        missingArguments.Add(pi.Name);
                    }
                    arguments[i] = Type.Missing;
                }
            }
        }
        if (missingArguments != null)
        {
            throw new MissingArgumentsActionException(missingArguments);
        }
        method.Invoke(target, arguments);
    }
Exemple #2
0
    public static MethodInfo getDispatchMethod(Type targetType, DynamicServerAction dynamicServerAction)
    {
        List <MethodInfo> actionMethods = getCandidateMethods(targetType, dynamicServerAction.action);
        MethodInfo        matchedMethod = null;
        int bestMatchCount = -1; // we do this so that

        // This is where the the actual matching occurs.  The matching is done strictly based on
        // variable names.  In the future, this could be modified to include type information from
        // the inbound JSON object by mapping JSON types to csharp primitive types
        // (i.e. number -> [short, float, int], bool -> bool, string -> string, dict -> object, list -> list)
        foreach (var method in actionMethods)
        {
            int             matchCount = 0;
            ParameterInfo[] mParams    = method.GetParameters();

            // mixing a ServerAction action with non-server action creates an ambiguous situation
            // if one parameter is missing from the overloaded method its not clear whether the caller
            // intended to call the ServerAction action or was simply missing on of the parameters for the overloaded
            // variant
            if (actionMethods.Count > 1 && mParams.Length == 1 && mParams[0].ParameterType == typeof(ServerAction))
            {
                throw new AmbiguousActionException("Mixing a ServerAction method with overloaded methods is not permitted");
            }

            // default to ServerAction method
            // this is also necessary, to allow Initialize to be
            // called in the AgentManager and an Agent, since we
            // pass a ServerAction through
            if (matchedMethod == null && mParams.Length == 1 && mParams[0].ParameterType == typeof(ServerAction))
            {
                matchedMethod = method;
            }
            else
            {
                foreach (var p in method.GetParameters())
                {
                    if (dynamicServerAction.ContainsKey(p.Name))
                    {
                        matchCount++;
                    }
                }
            }

            // preference is given to the method that matches all parameters for a method
            // even if another method has the same matchCount (but has more parameters)
            if (matchCount > bestMatchCount)
            {
                bestMatchCount = matchCount;
                matchedMethod  = method;
            }
        }

        return(matchedMethod);
    }
Exemple #3
0
    // look through all methods on a target type and attempt to get the MethodInfo
    // any ambiguous method will throw an exception.  This is used during testing.
    public static List <string> FindAmbiguousActions(Type targetType)
    {
        List <string> actions = new List <string>();

        System.Reflection.MethodInfo[] allMethods = targetType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
        HashSet <string> methodNames = new HashSet <string>();

        foreach (var method in allMethods)
        {
            methodNames.Add(method.Name);
        }
        foreach (var methodName in methodNames)
        {
            try {
                Dictionary <string, object> act = new Dictionary <string, object>();
                act["action"] = methodName;
                DynamicServerAction dynamicServerAction = new DynamicServerAction(act);
                MethodInfo          m = getDispatchMethod(targetType, dynamicServerAction);
            } catch (AmbiguousActionException) {
                actions.Add(methodName);
            }
        }
        return(actions);
    }