v9.10.2019.0101 全面巩固批量Insert/Update/Upsert,支持数据备份、恢复和同步,支持实体列表保存到文件以及加载
|
# ·´ÉäÀ©Õ¹ 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)
|