简介

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

Github地址

源代码

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

/// <summary>
/// AutoMapper扩展
/// </summary>
public static class Extensions
{
    /// <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="TSource">源类型</typeparam>
    /// <typeparam name="TDestination">目标类型</typeparam>
    /// <param name="source">源对象</param>
    /// <returns></returns>
    public static TDestination MapTo<TSource, TDestination>(this TSource 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 = GetObjectType(source.GetType());
        var destinationType = GetObjectType(typeof(TDestination));
        try
        {
            var map = Mapper.Configuration.FindTypeMapFor(sourceType,destinationType);
            if (map != null)
            {
                return Mapper.Map(source, destination);
            }
            var maps = Mapper.Configuration.GetAllTypeMaps();
            Mapper.Initialize(config =>
            {
                foreach (var item in maps)
                {
                    config.CreateMap(item.SourceType, item.DestinationType);
                }
                config.CreateMap(sourceType,destinationType);
            });

        }
        catch (InvalidOperationException)
        {
            Mapper.Initialize(config =>
            {
                config.CreateMap(sourceType, destinationType);
            });
        }
        return Mapper.Map(source, destination);
    }

    /// <summary>
    /// 获取对象类型
    /// </summary>
    /// <param name="source">类型</param>
    /// <returns></returns>
    private static Type GetObjectType(Type source)
    {
        if (source.IsGenericType && typeof(IEnumerable).IsAssignableFrom(source))
        {
            var type = source.GetGenericArguments()[0];
            return GetObjectType(type);
        }
        return source;
    }
}

参考

何镇汐大大

05-02 03:31