浏览代码

优化反射创建实例

懒得勤快 6 年之前
父节点
当前提交
ccf38fc77a

+ 2 - 2
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -1,8 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <TargetFramework>netcoreapp2.1</TargetFramework>
-    <Version>2.2.6.2</Version>
+    <Version>2.2.6.3</Version>
     <Authors>懒得勤快</Authors>
     <Company>masuit.com</Company>
     <Description>包含一些常用的操作类,大都是静态类,加密解密,反射操作,硬件信息,字符串扩展方法,日期时间扩展操作,大文件拷贝,图像裁剪,html处理,验证码、NoSql等常用封装。

+ 72 - 6
Masuit.Tools.Core/Masuit.Tools.Core.xml

@@ -5654,19 +5654,85 @@
             <param name="resName">嵌入资源相对路径</param>
             <returns>如没找到该资源则返回空字符</returns>
         </member>
-        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.CreateInstance``1(System.String)">
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance(System.Type)">
             <summary>
-            创建对应实例
+            获取默认实例
             </summary>
             <param name="type">类型</param>
-            <returns>对应实例</returns>
+            <returns></returns>
         </member>
-        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.CreateInstance``1(System.Type)">
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance(System.String)">
             <summary>
-            创建对应实例
+            获取默认实例
             </summary>
             <param name="type">类型</param>
-            <returns>对应实例</returns>
+            <returns></returns>
+        </member>
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance``1(System.Type,``0)">
+            <summary>
+            获取一个构造参数的实例
+            </summary>
+            <typeparam name="TArg">参数类型</typeparam>
+            <param name="type">实例类型</param>
+            <param name="argument">参数值</param>
+            <returns></returns>
+        </member>
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance``1(System.String,``0)">
+            <summary>
+            获取一个构造参数的实例
+            </summary>
+            <typeparam name="TArg">参数类型</typeparam>
+            <param name="type">实例类型</param>
+            <param name="argument">参数值</param>
+            <returns></returns>
+        </member>
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance``2(System.Type,``0,``1)">
+            <summary>
+            获取2个构造参数的实例
+            </summary>
+            <typeparam name="TArg1">参数类型</typeparam>
+            <typeparam name="TArg2">参数类型</typeparam>
+            <param name="type">实例类型</param>
+            <param name="argument1">参数值</param>
+            <param name="argument2">参数值</param>
+            <returns></returns>
+        </member>
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance``2(System.String,``0,``1)">
+            <summary>
+            获取2个构造参数的实例
+            </summary>
+            <typeparam name="TArg1">参数类型</typeparam>
+            <typeparam name="TArg2">参数类型</typeparam>
+            <param name="type">实例类型</param>
+            <param name="argument1">参数值</param>
+            <param name="argument2">参数值</param>
+            <returns></returns>
+        </member>
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance``3(System.Type,``0,``1,``2)">
+            <summary>
+            获取3个构造参数的实例
+            </summary>
+            <typeparam name="TArg1">参数类型</typeparam>
+            <typeparam name="TArg2">参数类型</typeparam>
+            <typeparam name="TArg3">参数类型</typeparam>
+            <param name="type">实例类型</param>
+            <param name="argument1">参数值</param>
+            <param name="argument2">参数值</param>
+            <param name="argument3">参数值</param>
+            <returns></returns>
+        </member>
+        <member name="M:Masuit.Tools.Reflection.ReflectionUtil.GetInstance``3(System.String,``0,``1,``2)">
+            <summary>
+            获取3个构造参数的实例
+            </summary>
+            <typeparam name="TArg1">参数类型</typeparam>
+            <typeparam name="TArg2">参数类型</typeparam>
+            <typeparam name="TArg3">参数类型</typeparam>
+            <param name="type">实例类型</param>
+            <param name="argument1">参数值</param>
+            <param name="argument2">参数值</param>
+            <param name="argument3">参数值</param>
+            <returns></returns>
         </member>
         <member name="T:Masuit.Tools.Security.Encrypt">
             <summary>

+ 145 - 24
Masuit.Tools.Core/Reflection/ReflectionUtil.cs

@@ -1,7 +1,10 @@
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
 using System.IO;
+using System.Linq;
+using System.Linq.Expressions;
 using System.Reflection;
 using System.Resources;
 using System.Text;
@@ -141,7 +144,7 @@ namespace Masuit.Tools.Reflection
             }
 
             FieldInfo fi = value.GetType().GetField(value.ToString());
-            DescriptionAttribute[] attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
+            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
             var text1 = (attributes.Length > 0) ? attributes[0].Description : value.ToString();
             if ((args != null) && (args.Length > 0))
             {
@@ -181,7 +184,7 @@ namespace Masuit.Tools.Reflection
 
             if (member.IsDefined(typeof(DescriptionAttribute), false))
             {
-                DescriptionAttribute[] attributes = (DescriptionAttribute[]) member.GetCustomAttributes(typeof(DescriptionAttribute), false);
+                DescriptionAttribute[] attributes = (DescriptionAttribute[])member.GetCustomAttributes(typeof(DescriptionAttribute), false);
                 text1 = attributes[0].Description;
             }
             else
@@ -343,7 +346,7 @@ namespace Masuit.Tools.Reflection
         {
             Assembly thisAssembly = Assembly.GetAssembly(assemblyType);
             ResourceManager rm = new ResourceManager(resourceHolder, thisAssembly);
-            return (Bitmap) rm.GetObject(imageName);
+            return (Bitmap)rm.GetObject(imageName);
         }
 
         /// <summary>
@@ -375,7 +378,7 @@ namespace Masuit.Tools.Reflection
                 return "";
             }
 
-            int iLen = (int) st.Length;
+            int iLen = (int)st.Length;
             byte[] bytes = new byte[iLen];
             st.Read(bytes, 0, iLen);
             return (bytes != null) ? Encoding.GetEncoding(charset).GetString(bytes) : "";
@@ -383,39 +386,157 @@ namespace Masuit.Tools.Reflection
 
         #endregion
 
-        #region 创建对应实例
+        #region 创建实例
 
         /// <summary>
-        /// 创建对应实例
+        /// 获取默认实例
         /// </summary>
         /// <param name="type">类型</param>
-        /// <returns>对应实例</returns>
-        public static T CreateInstance<T>(string type) where T : class
+        /// <returns></returns>
+        public static object GetInstance(this Type type)
         {
-            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
-            foreach (Assembly t in assemblies)
-            {
-                var tmp = t.GetType(type);
-                if (tmp != null)
-                {
-                    return t.CreateInstance(type) as T;
-                }
-            }
-
-            return null;
-            //return Assembly.GetExecutingAssembly().CreateInstance(type);
+            return GetInstance<TypeToIgnore>(type, null);
         }
 
         /// <summary>
-        /// 创建对应实例
+        /// 获取默认实例
         /// </summary>
         /// <param name="type">类型</param>
-        /// <returns>对应实例</returns>
-        public static T CreateInstance<T>(this Type type) where T : class
+        /// <returns></returns>
+        public static object GetInstance(string type)
+        {
+            return GetInstance<TypeToIgnore>(Type.GetType(type), null);
+        }
+
+        /// <summary>
+        /// 获取一个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg>(this Type type, TArg argument)
+        {
+            return GetInstance<TArg, TypeToIgnore>(type, argument, null);
+        }
+
+        /// <summary>
+        /// 获取一个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg>(string type, TArg argument)
+        {
+            return GetInstance<TArg, TypeToIgnore>(Type.GetType(type), argument, null);
+        }
+
+        /// <summary>
+        /// 获取2个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2>(this Type type, TArg1 argument1, TArg2 argument2)
         {
-            return CreateInstance<T>(type.FullName);
+            return GetInstance<TArg1, TArg2, TypeToIgnore>(type, argument1, argument2, null);
         }
 
+        /// <summary>
+        /// 获取2个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2>(string type, TArg1 argument1, TArg2 argument2)
+        {
+            return GetInstance<TArg1, TArg2, TypeToIgnore>(Type.GetType(type), argument1, argument2, null);
+        }
+
+        /// <summary>
+        /// 获取3个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <typeparam name="TArg3">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <param name="argument3">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2, TArg3>(this Type type, TArg1 argument1, TArg2 argument2, TArg3 argument3)
+        {
+            return InstanceCreationFactory<TArg1, TArg2, TArg3>.CreateInstanceOf(type, argument1, argument2, argument3);
+        }
+
+        /// <summary>
+        /// 获取3个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <typeparam name="TArg3">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <param name="argument3">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2, TArg3>(string type, TArg1 argument1, TArg2 argument2, TArg3 argument3)
+        {
+            return InstanceCreationFactory<TArg1, TArg2, TArg3>.CreateInstanceOf(Type.GetType(type), argument1, argument2, argument3);
+        }
+
+        private class TypeToIgnore
+        {
+        }
+
+        private static class InstanceCreationFactory<TArg1, TArg2, TArg3>
+        {
+            private static readonly Dictionary<Type, Func<TArg1, TArg2, TArg3, object>> InstanceCreationMethods = new Dictionary<Type, Func<TArg1, TArg2, TArg3, object>>();
+
+            public static object CreateInstanceOf(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3)
+            {
+                CacheInstanceCreationMethodIfRequired(type);
+
+                return InstanceCreationMethods[type].Invoke(arg1, arg2, arg3);
+            }
+
+            private static void CacheInstanceCreationMethodIfRequired(Type type)
+            {
+                if (InstanceCreationMethods.ContainsKey(type))
+                {
+                    return;
+                }
+
+                var argumentTypes = new[]
+                {
+                    typeof(TArg1),
+                    typeof(TArg2),
+                    typeof(TArg3)
+                };
+
+                Type[] constructorArgumentTypes = argumentTypes.Where(t => t != typeof(TypeToIgnore)).ToArray();
+                var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, constructorArgumentTypes, new ParameterModifier[0]);
+
+                var lamdaParameterExpressions = new[]
+                {
+                    Expression.Parameter(typeof(TArg1), "param1"),
+                    Expression.Parameter(typeof(TArg2), "param2"),
+                    Expression.Parameter(typeof(TArg3), "param3")
+                };
+
+                var constructorParameterExpressions = lamdaParameterExpressions.Take(constructorArgumentTypes.Length).ToArray();
+                var constructorCallExpression = Expression.New(constructor, constructorParameterExpressions);
+                var constructorCallingLambda = Expression.Lambda<Func<TArg1, TArg2, TArg3, object>>(constructorCallExpression, lamdaParameterExpressions).Compile();
+                InstanceCreationMethods[type] = constructorCallingLambda;
+            }
+        }
         #endregion
     }
 }

+ 2 - 2
Masuit.Tools/Properties/AssemblyInfo.cs

@@ -36,7 +36,7 @@ using System.Runtime.InteropServices;
 // 方法是按如下所示使用“*”: :
 // [assembly: AssemblyVersion("1.0.*")]
 
-[assembly: AssemblyVersion("2.2.6.2")]
-[assembly: AssemblyFileVersion("2.2.6.2")]
+[assembly: AssemblyVersion("2.2.6.3")]
+[assembly: AssemblyFileVersion("2.2.6.3")]
 [assembly: NeutralResourcesLanguage("zh-CN")]
 

+ 141 - 19
Masuit.Tools/Reflection/ReflectionUtil.cs

@@ -1,7 +1,10 @@
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
 using System.IO;
+using System.Linq;
+using System.Linq.Expressions;
 using System.Reflection;
 using System.Resources;
 using System.Text;
@@ -366,38 +369,157 @@ namespace Masuit.Tools.Reflection
 
         #endregion
 
-        #region 创建对应实例
+        #region 创建实例
 
         /// <summary>
-        /// 创建对应实例
+        /// 获取默认实例
         /// </summary>
         /// <param name="type">类型</param>
-        /// <returns>对应实例</returns>
-        public static T CreateInstance<T>(string type) where T : class
+        /// <returns></returns>
+        public static object GetInstance(this Type type)
         {
-            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
-            foreach (Assembly t in assemblies)
-            {
-                var tmp = t.GetType(type);
-                if (tmp != null)
-                {
-                    return t.CreateInstance(type) as T;
-                }
-            }
-
-            return null;
+            return GetInstance<TypeToIgnore>(type, null);
         }
 
         /// <summary>
-        /// 创建对应实例
+        /// 获取默认实例
         /// </summary>
         /// <param name="type">类型</param>
-        /// <returns>对应实例</returns>
-        public static T CreateInstance<T>(this Type type) where T : class
+        /// <returns></returns>
+        public static object GetInstance(string type)
+        {
+            return GetInstance<TypeToIgnore>(Type.GetType(type), null);
+        }
+
+        /// <summary>
+        /// 获取一个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg>(this Type type, TArg argument)
+        {
+            return GetInstance<TArg, TypeToIgnore>(type, argument, null);
+        }
+
+        /// <summary>
+        /// 获取一个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg>(string type, TArg argument)
+        {
+            return GetInstance<TArg, TypeToIgnore>(Type.GetType(type), argument, null);
+        }
+
+        /// <summary>
+        /// 获取2个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2>(this Type type, TArg1 argument1, TArg2 argument2)
+        {
+            return GetInstance<TArg1, TArg2, TypeToIgnore>(type, argument1, argument2, null);
+        }
+
+        /// <summary>
+        /// 获取2个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2>(string type, TArg1 argument1, TArg2 argument2)
         {
-            return CreateInstance<T>(type.FullName);
+            return GetInstance<TArg1, TArg2, TypeToIgnore>(Type.GetType(type), argument1, argument2, null);
         }
 
+        /// <summary>
+        /// 获取3个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <typeparam name="TArg3">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <param name="argument3">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2, TArg3>(this Type type, TArg1 argument1, TArg2 argument2, TArg3 argument3)
+        {
+            return InstanceCreationFactory<TArg1, TArg2, TArg3>.CreateInstanceOf(type, argument1, argument2, argument3);
+        }
+
+        /// <summary>
+        /// 获取3个构造参数的实例
+        /// </summary>
+        /// <typeparam name="TArg1">参数类型</typeparam>
+        /// <typeparam name="TArg2">参数类型</typeparam>
+        /// <typeparam name="TArg3">参数类型</typeparam>
+        /// <param name="type">实例类型</param>
+        /// <param name="argument1">参数值</param>
+        /// <param name="argument2">参数值</param>
+        /// <param name="argument3">参数值</param>
+        /// <returns></returns>
+        public static object GetInstance<TArg1, TArg2, TArg3>(string type, TArg1 argument1, TArg2 argument2, TArg3 argument3)
+        {
+            return InstanceCreationFactory<TArg1, TArg2, TArg3>.CreateInstanceOf(Type.GetType(type), argument1, argument2, argument3);
+        }
+
+        private class TypeToIgnore
+        {
+        }
+
+        private static class InstanceCreationFactory<TArg1, TArg2, TArg3>
+        {
+            private static readonly Dictionary<Type, Func<TArg1, TArg2, TArg3, object>> InstanceCreationMethods = new Dictionary<Type, Func<TArg1, TArg2, TArg3, object>>();
+
+            public static object CreateInstanceOf(Type type, TArg1 arg1, TArg2 arg2, TArg3 arg3)
+            {
+                CacheInstanceCreationMethodIfRequired(type);
+
+                return InstanceCreationMethods[type].Invoke(arg1, arg2, arg3);
+            }
+
+            private static void CacheInstanceCreationMethodIfRequired(Type type)
+            {
+                if (InstanceCreationMethods.ContainsKey(type))
+                {
+                    return;
+                }
+
+                var argumentTypes = new[]
+                {
+                    typeof(TArg1),
+                    typeof(TArg2),
+                    typeof(TArg3)
+                };
+
+                Type[] constructorArgumentTypes = argumentTypes.Where(t => t != typeof(TypeToIgnore)).ToArray();
+                var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, constructorArgumentTypes, new ParameterModifier[0]);
+
+                var lamdaParameterExpressions = new[]
+                {
+                    Expression.Parameter(typeof(TArg1), "param1"),
+                    Expression.Parameter(typeof(TArg2), "param2"),
+                    Expression.Parameter(typeof(TArg3), "param3")
+                };
+
+                var constructorParameterExpressions = lamdaParameterExpressions.Take(constructorArgumentTypes.Length).ToArray();
+                var constructorCallExpression = Expression.New(constructor, constructorParameterExpressions);
+                var constructorCallingLambda = Expression.Lambda<Func<TArg1, TArg2, TArg3, object>>(constructorCallExpression, lamdaParameterExpressions).Compile();
+                InstanceCreationMethods[type] = constructorCallingLambda;
+            }
+        }
         #endregion
     }
 }