ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AutoMapper扩展方法

2021-12-04 20:03:18  阅读:152  来源: 互联网

标签:Mapper return sourceType 扩展 source static destinationType AutoMapper 方法


出处:https://www.cnblogs.com/jianxuanbing/p/7122877.html

 

    /// <summary>
    /// Defines the <see cref="AutoMapperExtension" />.
    /// </summary>
    public static class AutoMapperExtension
    {
        /// <summary>
        /// 同步锁..
        /// </summary>
        private static readonly object Sync = new object();

        /// <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);
        }

        /// <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);
        }

        /// <summary>
        /// 集合列表类型映射.
        /// </summary>
        /// <typeparam name="TSource">数据源类型.</typeparam>
        /// <typeparam name="TDestination">目标对象类型.</typeparam>
        /// <param name="source">数据源.</param>
        /// <returns>.</returns>
        public static List<TDestination> MapTo<TSource, TDestination>(this IEnumerable<TSource> source)
            where TDestination : class
            where TSource : class
        {
            return MapTo<List<TDestination>>(source);
        }
    }

 

标签:Mapper,return,sourceType,扩展,source,static,destinationType,AutoMapper,方法
来源: https://www.cnblogs.com/cyjngup/p/15643036.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有