/// <summary>
        /// Obtains a list of all methods with the given <paramref name="methodName"/> on the given 
        /// <paramref name="obj" />, and invokes the best match for the parameters obtained from the 
        /// public properties of the supplied <paramref name="sample"/> object.
        /// TryCallMethod is very liberal and attempts to convert values that are not otherwise
        /// considered compatible, such as between strings and enums or numbers, Guids and byte[16], etc.
        /// </summary>
        /// <returns>The result of the invocation.</returns>
        public static object TryCallMethod( this object obj, string methodName, bool mustUseAllParameters, object sample )
        {
            Type sourceType = sample.GetType();
            var sourceInfo = new SourceInfo( sourceType );
            var paramValues = sourceInfo.GetParameterValues( sample );
			return obj.TryCallMethod( methodName, mustUseAllParameters, sourceInfo.ParamNames, sourceInfo.ParamTypes, paramValues );
        }
示例#2
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;
        }
示例#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);
        }
 /// <summary>
 /// Creates an instance of the given <paramref name="type"/> using the public properties of the 
 /// supplied <paramref name="sample"/> object as input.
 /// This method will try to determine the least-cost route to constructing the instance, which
 /// implies mapping as many properties as possible to constructor parameters. Remaining properties
 /// on the source are mapped to properties on the created instance or ignored if none matches.
 /// TryCreateInstance is very liberal and attempts to convert values that are not otherwise
 /// considered compatible, such as between strings and enums or numbers, Guids and byte[], etc.
 /// </summary>
 /// <returns>An instance of <paramref name="type"/>.</returns>
 public static object TryCreateInstance( this Type type, object sample )
 {
     Type sourceType = sample.GetType();
     SourceInfo sourceInfo = sourceInfoCache.Get( sourceType );
     if( sourceInfo == null )
     {
         sourceInfo = new SourceInfo( sourceType );
         sourceInfoCache.Insert( sourceType, sourceInfo );
     }
     object[] paramValues = sourceInfo.GetParameterValues( sample );
     MethodMap map = MapFactory.PrepareInvoke( type, sourceInfo.ParamNames, sourceInfo.ParamTypes, paramValues );
     return map.Invoke( paramValues );
 }
		/// <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 )
		{
			Type sourceType = sample.GetType();
			var sourceInfo = new SourceInfo( sourceType );
			bool isStatic = obj is Type;
			string[] names = sourceInfo.ParamNames;
			Type[] types = sourceInfo.ParamTypes;
			object[] values = sourceInfo.GetParameterValues( sample );
			if( names.Length != values.Length || names.Length != types.Length )
			{
				throw new ArgumentException( "Mismatching name, type and value arrays (must be of identical length)." );
			}
			MethodMap map = MapFactory.DetermineBestMethodMatch( methodPool, mustUseAllParameters, names, types, values );
			return isStatic ? map.Invoke( values ) : map.Invoke( obj, values );
		}
        /// <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)
        {
            Type sourceType = sample.GetType();
            var  sourceInfo = new SourceInfo(sourceType);
            bool isStatic   = obj is Type;

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

            return(isStatic ? map.Invoke(values) : map.Invoke(obj, values));
        }
        /// <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() ?? Constants.EmptyStringArray;
            object[]   values     = parameters.Values.ToArray() ?? Constants.EmptyObjectArray;
            Type[]     types      = values.ToTypeArray() ?? Type.EmptyTypes;
            bool       isStatic   = obj is Type;
            Type       type       = isStatic ? obj as Type : obj.GetType();
            SourceInfo 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));
        }
示例#8
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 );
 }
示例#9
0
		private static int[] GetSampleHashes()
		{
			var sources = new object[]
			              {
			              	new { }, new { Id = 42 }, new { Name = "Scar" }, new { Id = 42, Name = "Scar" },
			              	new { Id = 42, Birthday = DateTime.Now },
			              	new { Id = 42, Name = "Scar", Birthday = DateTime.Now, Dummy = 0 }
			              };
			int index = 0;
			var infos = new SourceInfo[ sources.Length ];
			Array.ForEach( sources, s => { infos[ index++ ] = SourceInfo.CreateFromType( s.GetType() ); } );
			index = 0;
			int[] hashes = new int[ sources.Length ];
			Array.ForEach( infos, i => { hashes[ index++ ] = i.GetHashCode(); } );
			return hashes;
		}