using AutoMapper; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Common { public static class MapperHelper { /// /// 同步锁 /// private static readonly object Sync = new object(); /// /// 将源对象映射到目标对象 /// /// 源类型 /// 目标类型 /// 源对象 /// 目标对象 public static TDestination MapTo(this TSource source, TDestination destination) { return MapTo(source, destination); } /// /// 将源对象映射到目标对象 /// /// 目标类型 /// 源对象 public static TDestination MapTo(this object source) where TDestination : new() { return MapTo(source, new TDestination()); } /// /// 将源对象映射到目标对象 /// private static TDestination MapTo(object source, TDestination destination) { if (source == null) throw new ArgumentNullException(nameof(source)); if (destination == null) throw new ArgumentNullException(nameof(destination)); var sourceType = GetType(source); var destinationType = GetType(destination); var map = GetMap(sourceType, destinationType); if (map != null) return Mapper.Map(source, destination); lock (Sync) { map = GetMap(sourceType, destinationType); if (map != null) return Mapper.Map(source, destination); InitMaps(sourceType, destinationType); } return Mapper.Map(source, destination); } /// /// 获取类型 /// private static Type GetType(object obj) { var type = obj.GetType(); if ((obj is System.Collections.IEnumerable) == false) return type; if (type.IsArray) return type.GetElementType(); var genericArgumentsTypes = type.GetTypeInfo().GetGenericArguments(); if (genericArgumentsTypes == null || genericArgumentsTypes.Length == 0) throw new ArgumentException("泛型类型参数不能为空"); return genericArgumentsTypes[0]; } /// /// 获取映射配置 /// private static TypeMap GetMap(Type sourceType, Type destinationType) { try { return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType); } catch (InvalidOperationException) { lock (Sync) { try { return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType); } catch (InvalidOperationException) { InitMaps(sourceType, destinationType); } return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType); } } } /// /// 初始化映射配置 /// private static void InitMaps(Type sourceType, Type destinationType) { try { var maps = Mapper.Configuration.GetAllTypeMaps(); Mapper.Initialize(config => { ClearConfig(); foreach (var item in maps) config.CreateMap(item.SourceType, item.DestinationType); config.CreateMap(sourceType, destinationType); }); } catch (InvalidOperationException) { Mapper.Initialize(config => { config.CreateMap(sourceType, destinationType); }); } } /// /// 清空配置 /// private static void ClearConfig() { var typeMapper = typeof(Mapper).GetTypeInfo(); var configuration = typeMapper.GetDeclaredField("_configuration"); configuration.SetValue(null, null, BindingFlags.Static, null, CultureInfo.CurrentCulture); } /// /// 将源集合映射到目标集合 /// /// 目标元素类型,范例:Sample,不要加List /// 源集合 public static List MapToList(this System.Collections.IEnumerable source) { return MapTo>(source); } } }