예제 #1
0
        private static MethodMap DetermineBestMatch(IEnumerable <MethodBase> methods, bool mustUseAllParameters,
                                                    string[] paramNames, Type[] parameterTypes, object[] sampleParamValues)
        {
            MethodMap bestMap = null;

            foreach (MethodBase method in methods)
            {
                MethodMap map = CreateMap(method, paramNames, parameterTypes, sampleParamValues, mustUseAllParameters);
                if (map != null && map.IsValid)
                {
                    bool isBetter = bestMap == null;
                    isBetter |= map.IsPerfectMatch;
                    isBetter |= bestMap != null &&
                                (map.Cost < bestMap.Cost ||
                                 (map.Cost == bestMap.Cost && map.RequiredParameterCount > bestMap.RequiredParameterCount));
                    isBetter &= map.IsValid;
                    if (isBetter)
                    {
                        bestMap = map;
                    }
                }
            }
            if (bestMap != null)
            {
                bestMap.InitializeInvoker();
                return(bestMap);
            }
            return(null);
        }
예제 #2
0
        /// <summary>
        /// Invoke the best available match for the supplied parameters. If no method can be called
        /// using the supplied parameters, an exception is thrown.
        /// </summary>
        /// <param name="obj">The object on which to invoke a method.</param>
        /// <param name="mustUseAllParameters">Specifies whether all supplied parameters must be used in the
        /// invocation. Unless you know what you are doing you should pass true for this parameter.</param>
        /// <param name="sample">The object whose public properties will be used as parameters.</param>
        /// <returns>The return value of the invocation.</returns>
        public object Invoke(object obj, bool mustUseAllParameters, object sample)
        {
            if (obj == null || sample == null)
            {
                throw new ArgumentException("Missing or invalid argument: " + (obj == null ? "obj" : "sample"));
            }
            var sourceInfo = SourceInfo.CreateFromType(sample.GetType());

            // check to see if we already have a map for best match
            MethodMap map = mapCache.Get(sourceInfo);

            object[] values = sourceInfo.GetParameterValues(sample);
            if (map == null)
            {
                string[] names = sourceInfo.ParamNames;
                Type[]   types = sourceInfo.ParamTypes;
                if (names.Length != values.Length || names.Length != types.Length)
                {
                    throw new ArgumentException("Mismatching name, type and value arrays (must be of identical length).");
                }
                map = MapFactory.DetermineBestMethodMatch(methodPool, mustUseAllParameters, names, types, values);
                mapCache.Insert(sourceInfo, map);
            }
            bool isStatic = obj is Type;

            return(isStatic ? map.Invoke(values) : map.Invoke(obj, values));
        }
예제 #3
0
        public static MethodMap PrepareInvoke(Type type, string[] paramNames, Type[] parameterTypes,
                                              object[] sampleParamValues)
        {
            SourceInfo sourceInfo = new SourceInfo(type, paramNames, parameterTypes);
            MethodMap  map        = ctorMapCache.Get(sourceInfo);

            if (map == null)
            {
                map = DetermineBestConstructorMatch(type, paramNames, parameterTypes, sampleParamValues);
                ctorMapCache.Insert(sourceInfo, map);
            }
            return(map);
        }
예제 #4
0
        internal static MethodMap DetermineBestConstructorMatch(Type type, string[] paramNames, Type[] parameterTypes,
                                                                object[] sampleParamValues)
        {
            MethodMap map = DetermineBestMatch(type.GetConstructors(), false, paramNames, parameterTypes, sampleParamValues);

            if (map != null)
            {
                return(map);
            }
            var sb = new StringBuilder();

            sb.AppendFormat("No constructor found for type {0} using parameters:{1}", type.Name, Environment.NewLine);
            sb.AppendFormat("{0}{1}", string.Join(", ", Enumerable.Range(0, paramNames.Length).Select(i => string.Format("{0}:{1}", paramNames[i], parameterTypes[i])).ToArray()), Environment.NewLine);
            throw new MissingMethodException(sb.ToString());
        }
예제 #5
0
        internal static MethodMap DetermineBestMethodMatch(IEnumerable <MethodBase> methods, bool mustUseAllParameters, string[] paramNames,
                                                           Type[] parameterTypes, object[] sampleParamValues)
        {
            MethodMap map = DetermineBestMatch(methods, mustUseAllParameters, paramNames, parameterTypes, sampleParamValues);

            if (map != null)
            {
                return(map);
            }
            var sb = new StringBuilder();

            sb.AppendFormat("No method found ({0} candidates examined) matching the parameters:{1}", methods.ToList().Count, Environment.NewLine);
            //sb.AppendFormat( "{0}{1}", Format( parameters, "=", ", " ), Environment.NewLine );
            sb.AppendFormat("{0}{1}", string.Join(", ", Enumerable.Range(0, paramNames.Length).Select(i => string.Format("{0}:{1}", paramNames[i], parameterTypes[i])).ToArray()), Environment.NewLine);
            throw new MissingMethodException(sb.ToString());
        }
예제 #6
0
        /// <summary>
        /// Invoke the best available match for the supplied parameters.
        /// If no method can be called using the supplied parameters, an exception is thrown.
        /// </summary>
        /// <param name="obj">The object on which to invoke a method.</param>
        /// <param name="mustUseAllParameters">Specifies whether all supplied parameters must be used in the
        /// invocation. Unless you know what you are doing you should pass true for this parameter.</param>
        /// <param name="parameters">A dictionary of parameter name/value pairs.</param>
        /// <returns>The return value of the invocation.</returns>
        public object Invoke(object obj, bool mustUseAllParameters, Dictionary <string, object> parameters)
        {
            if (obj == null || parameters == null)
            {
                throw new ArgumentException("Missing or invalid argument: " + (obj == null ? "obj" : "parameters"));
            }
            string[] names      = parameters.Keys.ToArray() ?? new string[0];
            object[] values     = parameters.Values.ToArray() ?? new object[0];
            Type[]   types      = values.ToTypeArray() ?? new Type[0];
            bool     isStatic   = obj is Type;
            var      type       = isStatic ? obj as Type : obj.GetType();
            var      sourceInfo = new SourceInfo(type, names, types);
            // check to see if we already have a map for best match
            MethodMap map = mapCache.Get(sourceInfo);

            if (map == null)
            {
                map = MapFactory.DetermineBestMethodMatch(methodPool, mustUseAllParameters, names, types, values);
                mapCache.Insert(sourceInfo, map);
            }
            return(isStatic ? map.Invoke(values) : map.Invoke(obj, values));
        }