using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using Omu.ValueInjecter; using Omu.ValueInjecter.Injections; using Volo.Abp; namespace Faster.Zheng.Winin.Extensions; /// /// 对象映射 /// public static class ObjectMapperExtensions { /// /// 从模型更新实体 /// public static T FromObject(this T to, object from) { try { to.InjectFrom(from); return to; } catch (Exception ex) { throw new UserFriendlyException($"{from.GetType().FullName}映射到${typeof(T).FullName}时失败:{ex.Message},{ex}"); } } /// /// 从实体创建模型 /// /// /// /// public static T ToObject(this object from) { try { if (typeof(T).IsGenericType && typeof(T).IsAssignableTo(typeof(IList)) && from is IList list) { var toListType = typeof(T); var elementType = typeof(T).GetGenericArguments()[0]; var toList = (IList)Activator.CreateInstance(typeof(T))!; var fromList = list; foreach (var item in fromList) { toList.Add(Activator.CreateInstance(elementType).InjectFrom(item)); } return (T)toList; } return (T)Activator.CreateInstance().InjectFrom(from); } catch (Exception ex) { throw new UserFriendlyException($"{from.GetType().FullName}映射到${typeof(T).FullName}时失败:{ex.Message},{ex}"); } } private class DeepInjection : LoopInjection { protected override bool MatchTypes(Type sourceType, Type targetType) { if (sourceType != typeof(string) && targetType != typeof(string) && sourceType.IsGenericType && targetType.IsGenericType && sourceType.IsAssignableTo(typeof(IEnumerable)) && sourceType.IsAssignableTo(typeof(IEnumerable)) ) { return true; } return base.MatchTypes(sourceType, targetType); } protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) { if (sp.PropertyType != typeof(string) && sp.PropertyType != typeof(string) && sp.PropertyType.IsAssignableTo(typeof(IList)) && tp.PropertyType.IsAssignableTo(typeof(IList))) { var targetGenericType = tp.PropertyType.GetGenericArguments()[0]; var listType = typeof(List<>).MakeGenericType(targetGenericType); var addMethod = listType.GetMethod("Add"); var list = Activator.CreateInstance(listType); var sourceList = (IList)sp.GetValue(source); foreach (var item in sourceList) { addMethod.Invoke(list, new[] { Activator.CreateInstance(targetGenericType).FromObject(item) }); } tp.SetValue(target, list); return; } base.SetValue(source, target, sp, tp); } } private class DeepInjectionForUpdate : DeepInjection { protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) { //if (tp.GetCustomAttribute() != null) //{ // return; //} base.SetValue(source, target, sp, tp); } } }