• AutoMapper6扩展


    简介

    很多时候我们使用AutoMapper的时候,都需要进行一个配置才可以使用Mapper.Map<Source,Target>(entity);。如果不进行配置则会报错。
    如果实体过多,有时候会忘记是否有配置,只有运行的时候才会发现这个BUG。

    源代码地址

    源代码

    该扩展基于AutoMapper 6.x版本,因此需要从Nuget下载相应的包。
    该扩展对于Object以及List<T>进行了兼容支持,因此MapTo<TSource,TDestination>()可以直接映射实体与泛型列表。

    /// <summary>
    /// AutoMapper 对象映射扩展
    /// </summary>
    public static partial class Extensions
    {
        /// <summary>
        /// 同步锁
        /// </summary>
        private static readonly object Sync=new object();
    
        #region MapTo(将源对象映射到目标对象)
    
        /// <summary>
        /// 将源对象映射到目标对象
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TDestination">目标类型</typeparam>
        /// <param name="source">源对象</param>
        /// <param name="destination">目标对象</param>
        /// <returns></returns>
        public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
        {
            return MapTo<TDestination>(source, destination);
        }
    
        /// <summary>
        /// 将源对象映射到目标对象
        /// </summary>
        /// <typeparam name="TDestination">目标类型</typeparam>
        /// <param name="source">源对象</param>
        /// <returns></returns>
        public static TDestination MapTo<TDestination>(this object source) where TDestination : new()
        {
            return MapTo(source, new TDestination());
        }
    
        /// <summary>
        /// 将源对象映射到目标对象
        /// </summary>
        /// <typeparam name="TDestination">目标类型</typeparam>
        /// <param name="source">源对象</param>
        /// <param name="destination">目标对象</param>
        /// <returns></returns>
        private static TDestination MapTo<TDestination>(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);
        }
    
        /// <summary>
        /// 获取映射配置
        /// </summary>
        /// <param name="sourceType">源类型</param>
        /// <param name="destinationType">目标类型</param>
        /// <returns></returns>
        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);
                }
            }
        }
    
        /// <summary>
        /// 获取类型
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        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];
        }
    
        /// <summary>
        /// 初始化映射配置
        /// </summary>
        /// <param name="sourceType">源类型</param>
        /// <param name="destinationType">目标类型</param>
        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);
                });
            }
        }
    
        /// <summary>
        /// 清空配置
        /// </summary>
        private static void ClearConfig()
        {
            var typeMapper = typeof(Mapper).GetTypeInfo();
            var configuration = typeMapper.GetDeclaredField("_configuration");
            configuration.SetValue(null, null, BindingFlags.Static, null, CultureInfo.CurrentCulture);
        }
    
        #endregion
    
        #region MapToList(将源集合映射到目标列表)
    
        /// <summary>
        /// 将源集合映射到目标列表
        /// </summary>
        /// <typeparam name="TDestination">目标元素类型,范例:Sample,不用加List</typeparam>
        /// <param name="source">源集合</param>
        /// <returns></returns>
        public static List<TDestination> MapToList<TDestination>(this System.Collections.IEnumerable source)
        {
            return MapTo<List<TDestination>>(source);
        }
    
        #endregion
    }
    
  • 相关阅读:
    spark 随意笔记
    c#读取输入字符串,从数据源中查找以该字符串开头的所有字符串(使用正则表达式)
    我的收藏链接地址
    SQL查询时,遇到用到关键词作的字段。将该字段用一对中括号括起来[]
    SQL数据类型相互转换
    Javascript获取系统当前时间
    节点类型nodeType的取值
    混合布局编程挑战
    Webstorm破解方法
    二列布局
  • 原文地址:https://www.cnblogs.com/jianxuanbing/p/7122877.html
Copyright © 2020-2023  润新知