v9.10.2019.0101  全面巩固批量Insert/Update/Upsert,支持数据备份、恢复和同步,支持实体列表保存到文件以及加载
大石头 authored at 2019-01-01 13:38:33
10.99 KiB
X
# ·´ÉäÀ©Õ¹ Reflect ## ¸ÅÊö `Reflect` ÊÇ NewLife.Core ÖеĸßÐÔÄÜ·´É乤¾ßÀ࣬ÌṩÀàÐÍ»ñÈ¡¡¢·½·¨µ÷Óá¢ÊôÐÔ¶Áд¡¢¶ÔÏó¿½±´µÈ¹¦ÄÜ¡£Ö§³Ö˽ÓгÉÔ±·ÃÎÊ¡¢ºöÂÔ´óСдƥÅ䣬²¢Í¨¹ý `IReflect` ½Ó¿ÚÖ§³Ö¿ÉÌæ»»µÄ·´ÉäʵÏÖ¡£ **ÃüÃû¿Õ¼ä**£º`NewLife.Reflection` **ÎĵµµØÖ·**£ºhttps://newlifex.com/core/reflect ## ºËÐÄÌØÐÔ - **¸ßÐÔÄÜ**£ºÄ¬ÈÏʵÏÖ»ùÓÚ»º´æ£¬Ö§³ÖÇл»Îª Emit ¸ßÐÔÄÜʵÏÖ - **Ò×ÓÃÐÔ**£ºËùÓз½·¨¶¼ÒÔÀ©Õ¹·½·¨ÐÎʽÌṩ - **ÍêÕûÐÔ**£ºÖ§³Ö˽ÓгÉÔ±¡¢¾²Ì¬³ÉÔ±¡¢¼Ì³Ð³ÉÔ±µÄ·ÃÎÊ - **Áé»îÐÔ**£ºÖ§³ÖºöÂÔ´óСдµÄ³ÉԱƥÅä - **¿ÉÀ©Õ¹**£ºÍ¨¹ý `IReflect` ½Ó¿ÚÖ§³Ö×Ô¶¨ÒåʵÏÖ ## ¿ìËÙ¿ªÊ¼ ```csharp using NewLife.Reflection; // ´´½¨ÊµÀý var obj = typeof(MyClass).CreateInstance(); // µ÷Ó÷½·¨ obj.Invoke("DoWork", "param1", 123); // ¶ÁÈ¡ÊôÐÔ var value = obj.GetValue("Name"); // ÉèÖÃÊôÐÔ obj.SetValue("Name", "NewValue"); // ¶ÔÏó¿½±´ var target = new MyClass(); target.Copy(source); ``` ## API ²Î¿¼ ### ÀàÐÍ»ñÈ¡ #### GetTypeEx ```csharp public static Type? GetTypeEx(this String typeName) ``` ¸ù¾ÝÀàÐÍÃû³Æ»ñÈ¡ÀàÐÍ£¬¿ÉËÑË÷µ±Ç°Ä¿Â¼ DLL ²¢×Ô¶¯¼ÓÔØ¡£ **ʾÀý**£º ```csharp // »ñȡϵͳÀàÐÍ var type1 = "System.String".GetTypeEx(); // »ñÈ¡´øÃüÃû¿Õ¼äµÄÀàÐÍ var type2 = "MyApp.Models.User".GetTypeEx(); // »ñÈ¡³ÌÐò¼¯ÏÞ¶¨ÃûÀàÐÍ var type3 = "MyApp.Models.User, MyApp".GetTypeEx(); ``` ### ³ÉÔ±»ñÈ¡ #### GetMethodEx ```csharp public static MethodInfo? GetMethodEx(this Type type, String name, params Type[] paramTypes) ``` »ñÈ¡·½·¨£¬Ö§³Ö²ÎÊýÀàÐÍÆ¥Åä¡£ **ʾÀý**£º ```csharp // »ñÈ¡Î޲η½·¨ var method1 = typeof(MyClass).GetMethodEx("DoWork"); // »ñÈ¡´ø²Î·½·¨ var method2 = typeof(MyClass).GetMethodEx("DoWork", typeof(String), typeof(Int32)); ``` #### GetMethodsEx ```csharp public static MethodInfo[] GetMethodsEx(this Type type, String name, Int32 paramCount = -1) ``` »ñȡָ¶¨Ãû³ÆµÄ·½·¨¼¯ºÏ£¬Ö§³Ö°´²ÎÊý¸öÊý¹ýÂË¡£ **ʾÀý**£º ```csharp // »ñÈ¡ËùÓÐÃûΪ DoWork µÄ·½·¨ var methods1 = typeof(MyClass).GetMethodsEx("DoWork"); // »ñÈ¡²ÎÊý¸öÊýΪ 2 µÄ DoWork ·½·¨ var methods2 = typeof(MyClass).GetMethodsEx("DoWork", 2); ``` #### GetPropertyEx ```csharp public static PropertyInfo? GetPropertyEx(this Type type, String name, Boolean ignoreCase = false) ``` »ñÈ¡ÊôÐÔ£¬ËÑË÷˽ÓС¢¾²Ì¬¡¢»ùÀà³ÉÔ±¡£ **ʾÀý**£º ```csharp // ¾«È·Æ¥Åä var prop1 = typeof(MyClass).GetPropertyEx("Name"); // ºöÂÔ´óСд var prop2 = typeof(MyClass).GetPropertyEx("name", true); // »ñȡ˽ÓÐÊôÐÔ var prop3 = typeof(MyClass).GetPropertyEx("_internalValue"); ``` #### GetFieldEx ```csharp public static FieldInfo? GetFieldEx(this Type type, String name, Boolean ignoreCase = false) ``` »ñÈ¡×ֶΣ¬ËÑË÷˽ÓС¢¾²Ì¬¡¢»ùÀà³ÉÔ±¡£ **ʾÀý**£º ```csharp var field = typeof(MyClass).GetFieldEx("_count"); ``` #### GetMemberEx ```csharp public static MemberInfo? GetMemberEx(this Type type, String name, Boolean ignoreCase = false) ``` »ñÈ¡³ÉÔ±£¨ÊôÐÔ»ò×ֶΣ©£¬ÓÅÏÈ·µ»ØÊôÐÔ¡£ **ʾÀý**£º ```csharp var member = typeof(MyClass).GetMemberEx("Name", true); ``` #### GetFields / GetProperties ```csharp public static IList<FieldInfo> GetFields(this Type type, Boolean baseFirst) public static IList<PropertyInfo> GetProperties(this Type type, Boolean baseFirst) ``` »ñÈ¡ÓÃÓÚÐòÁл¯µÄ×Ö¶Î/ÊôÐÔÁÐ±í¡£ **²ÎÊý˵Ã÷**£º - `baseFirst`£ºÊÇ·ñ»ùÀà³ÉÔ±ÓÅÏÈÅÅÐò **ʾÀý**£º ```csharp // »ñÈ¡ËùÓпÉÐòÁл¯ÊôÐÔ£¬»ùÀàÓÅÏÈ var props = typeof(MyClass).GetProperties(baseFirst: true); // »ñÈ¡ËùÓпÉÐòÁл¯×Ö¶Î var fields = typeof(MyClass).GetFields(baseFirst: false); ``` ### ʵÀý´´½¨Óë·½·¨µ÷Óà #### CreateInstance ```csharp public static Object? CreateInstance(this Type type, params Object?[] parameters) ``` ·´Éä´´½¨Ö¸¶¨ÀàÐ͵ÄʵÀý¡£ **ʾÀý**£º ```csharp // µ÷ÓÃÎ޲ι¹Ô캯Êý var obj1 = typeof(MyClass).CreateInstance(); // µ÷Óôø²Î¹¹Ô캯Êý var obj2 = typeof(MyClass).CreateInstance("name", 123); ``` #### Invoke ```csharp public static Object? Invoke(this Object target, String name, params Object?[] parameters) public static Object? Invoke(this Object? target, MethodBase method, params Object?[]? parameters) ``` ·´Éäµ÷Ó÷½·¨¡£ **ʾÀý**£º ```csharp var obj = new MyClass(); // µ÷ÓÃʵÀý·½·¨ var result = obj.Invoke("Calculate", 10, 20); // µ÷Óþ²Ì¬·½·¨£¨target ΪÀàÐÍ£© var result2 = typeof(MyClass).Invoke("StaticMethod", "param"); // µ÷ÓÃ˽Óз½·¨ var result3 = obj.Invoke("PrivateMethod"); ``` #### TryInvoke ```csharp public static Boolean TryInvoke(this Object target, String name, out Object? value, params Object?[] parameters) ``` ³¢ÊÔµ÷Ó÷½·¨£¬²»´æÔÚʱ·µ»Ø false ¶ø²»Å׳öÒì³£¡£ **ʾÀý**£º ```csharp if (obj.TryInvoke("MaybeExists", out var result, "param")) { Console.WriteLine($"½á¹û: {result}"); } else { Console.WriteLine("·½·¨²»´æÔÚ"); } ``` #### InvokeWithParams ```csharp public static Object? InvokeWithParams(this Object? target, MethodBase method, IDictionary? parameters) ``` ʹÓÃ×Öµä²ÎÊýµ÷Ó÷½·¨£¬ÊʺϲÎÊýÃûÆ¥Å䳡¾°¡£ **ʾÀý**£º ```csharp var parameters = new Dictionary<String, Object> { ["name"] = "test", ["count"] = 10 }; var result = obj.InvokeWithParams(method, parameters); ``` ### ÊôÐÔ¶Áд #### GetValue ```csharp public static Object? GetValue(this Object target, String name, Boolean throwOnError = true) public static Object? GetValue(this Object? target, MemberInfo member) ``` »ñÈ¡ÊôÐÔ/×Ö¶ÎÖµ¡£ **ʾÀý**£º ```csharp var obj = new MyClass { Name = "test" }; // °´Ãû³Æ»ñÈ¡ var name = obj.GetValue("Name"); // ²»´æÔÚʱ·µ»Ø null ¶ø²»Å×Òì³£ var value = obj.GetValue("NotExists", throwOnError: false); // °´³ÉÔ±»ñÈ¡ var prop = typeof(MyClass).GetPropertyEx("Name"); var name2 = obj.GetValue(prop); ``` #### SetValue ```csharp public static Boolean SetValue(this Object target, String name, Object? value) public static void SetValue(this Object target, MemberInfo member, Object? value) ``` ÉèÖÃÊôÐÔ/×Ö¶ÎÖµ¡£ **ʾÀý**£º ```csharp var obj = new MyClass(); // °´Ãû³ÆÉèÖà obj.SetValue("Name", "newValue"); // °´³ÉÔ±ÉèÖà var prop = typeof(MyClass).GetPropertyEx("Name"); obj.SetValue(prop, "anotherValue"); // ¼ì²éÊÇ·ñÉèÖóɹ¦ if (obj.SetValue("MaybeExists", "value")) { Console.WriteLine("ÉèÖóɹ¦"); } ``` ### ¶ÔÏó¿½±´ #### Copy ```csharp public static void Copy(this Object target, Object src, Boolean deep = false, params String[] excludes) public static void Copy(this Object target, IDictionary<String, Object?> dic, Boolean deep = false) ``` ´ÓÔ´¶ÔÏó»ò×ֵ俽±´Êý¾Ýµ½Ä¿±ê¶ÔÏó¡£ **²ÎÊý˵Ã÷**£º - `deep`£ºÊÇ·ñÉî¶È¿½±´£¨¸´ÖÆÖµ¶ø·ÇÒýÓã© - `excludes`£ºÒªÅųýµÄ³ÉÔ±Ãû³Æ **ʾÀý**£º ```csharp var source = new User { Name = "ÕÅÈý", Age = 25 }; var target = new UserDto(); // dz¿½±´ target.Copy(source); // É±´ target.Copy(source, deep: true); // ÅųýijЩ×Ö¶Î target.Copy(source, excludes: "Password", "Secret"); // ´Ó×ֵ俽±´ var dic = new Dictionary<String, Object?> { ["Name"] = "ÀîËÄ", ["Age"] = 30 }; target.Copy(dic); ``` ### ÀàÐ͸¨Öú #### GetElementTypeEx ```csharp public static Type? GetElementTypeEx(this Type type) ``` »ñÈ¡ÀàÐ͵ÄÔªËØÀàÐÍ£¨¼¯ºÏ¡¢Êý×éµÈ£©¡£ **ʾÀý**£º ```csharp typeof(List<String>).GetElementTypeEx() // typeof(String) typeof(String[]).GetElementTypeEx() // typeof(String) typeof(Dictionary<String, Int32>).GetElementTypeEx() // typeof(KeyValuePair<String, Int32>) ``` #### ChangeType ```csharp public static Object? ChangeType(this Object? value, Type conversionType) public static TResult? ChangeType<TResult>(this Object? value) ``` ÀàÐÍת»»¡£ **ʾÀý**£º ```csharp // ·ºÐÍת»» var num = "123".ChangeType<Int32>(); // 123 var date = "2024-01-15".ChangeType<DateTime>(); // ·Ç·ºÐÍת»» var value = "true".ChangeType(typeof(Boolean)); ``` #### GetName ```csharp public static String GetName(this Type type, Boolean isfull = false) ``` »ñÈ¡ÀàÐ͵ÄÓѺÃÃû³Æ¡£ **ʾÀý**£º ```csharp typeof(List<String>).GetName() // "List<String>" typeof(List<String>).GetName(true) // "System.Collections.Generic.List<System.String>" typeof(Dictionary<String, Int32>).GetName() // "Dictionary<String, Int32>" ``` ## ʹÓó¡¾° ### 1. ORM ʵÌåÓ³Éä ```csharp public class EntityMapper { public T Map<T>(IDataReader reader) where T : new() { var entity = new T(); var props = typeof(T).GetProperties(baseFirst: false); foreach (var prop in props) { var ordinal = reader.GetOrdinal(prop.Name); if (ordinal >= 0 && !reader.IsDBNull(ordinal)) { var value = reader.GetValue(ordinal); entity.SetValue(prop, value); } } return entity; } } ``` ### 2. ÅäÖÃ°ó¶¨ ```csharp public class ConfigBinder { public void Bind(Object target, IConfiguration config) { var props = target.GetType().GetProperties(baseFirst: true); foreach (var prop in props) { var value = config[prop.Name]; if (value != null) { var converted = value.ChangeType(prop.PropertyType); target.SetValue(prop, converted); } } } } ``` ### 3. ²å¼þϵͳ ```csharp public class PluginLoader { public IPlugin? LoadPlugin(String typeName) { var type = typeName.GetTypeEx(); if (type == null) return null; return type.CreateInstance() as IPlugin; } public void InvokeAction(IPlugin plugin, String action, params Object[] args) { if (plugin.TryInvoke(action, out var result, args)) { Console.WriteLine($"Ö´Ðгɹ¦: {result}"); } } } ``` ### 4. DTO ת»» ```csharp public static class DtoExtensions { public static TDto ToDto<TDto>(this Object entity) where TDto : new() { var dto = new TDto(); dto.Copy(entity); return dto; } public static void UpdateFrom(this Object entity, Object dto, params String[] excludes) { entity.Copy(dto, excludes: excludes); } } // ʹÓà var dto = user.ToDto<UserDto>(); user.UpdateFrom(dto, "Id", "CreateTime"); ``` ## ×î¼Ñʵ¼ù ### 1. ʹÓà TryInvoke ±ÜÃâÒì³£ ```csharp // ? ÍÆ¼ö£ºÊ¹Óà TryInvoke if (obj.TryInvoke("Method", out var result)) { // ´¦Àí½á¹û } // ? ²»ÍƼö£º¿ÉÄÜÅ×Òì³£ try { var result = obj.Invoke("Method"); } catch (XException) { } ``` ### 2. »º´æ·´ÉäÔªÊý¾Ý ```csharp // ? ÍÆ¼ö£º»º´æ PropertyInfo private static readonly PropertyInfo _nameProp = typeof(User).GetPropertyEx("Name"); public String GetName(User user) => user.GetValue(_nameProp) as String; // ? ²»ÍƼö£ºÃ¿´Î¶¼²éÕÒ public String GetName(User user) => user.GetValue("Name") as String; ``` ### 3. ʹÓúöÂÔ´óСдƥÅä ```csharp // ´¦Àí JSON ·´ÐòÁл¯µÈ³¡¾° var value = obj.GetValue("username", throwOnError: false); if (value == null) { // ³¢ÊÔºöÂÔ´óСд var member = obj.GetType().GetMemberEx("username", ignoreCase: true); if (member != null) value = obj.GetValue(member); } ``` ## ÐÔÄÜ˵Ã÷ - ĬÈÏ `DefaultReflect` ʵÏÖʹÓûº´æ£¬Êʺϴó¶àÊý³¡¾° - ¸ßƵ·´É䳡¾°¿ÉÇл»Îª `EmitReflect` ʵÏÖ£º ```csharp Reflect.Provider = new EmitReflect(); ``` - `GetProperties` ºÍ `GetFields` ½á¹û»á±»»º´æ - ³ÉÔ±²éÕÒʹÓÃ×ֵ仺´æ£¬Ê״ηÃÎʺóÐÔÄܽӽüÖ±½Óµ÷Óà ## Ïà¹ØÁ´½Ó - [ÔËÐÐʱÐÅÏ¢ Runtime](/NewLife/X/Blob/dev/Doc/runtime-ÔËÐÐʱÐÅÏ¢Runtime.md) - [½Å±¾ÒýÇæ ScriptEngine](/NewLife/X/Blob/dev/Doc/script_engine-½Å±¾ÒýÇæScriptEngine.md) - [¶ÔÏóÈÝÆ÷ ObjectContainer](/NewLife/X/Blob/dev/Doc/object_container-¶ÔÏóÈÝÆ÷ObjectContainer.md)