AutoMapper
- AutoMapper 接触发现还是比较实用的。
- AutoMapper 主要是自动映射对象类的提供者。
- 使用AutoMapper可以对实体进行转换,AutoMapper是对象到对象的映射工具。在完成映射规则之后,AutoMapper可以将源对象转换为目标对象。
配置AutoMapper映射规则,一般先初始化配置,一个应用只需初始化一次,如果放到静态类中,多次初始化在6.0之后会出现异常的。
Mapper.Initialize(cfg => cfg.CreateMap<Order, OrderDto>());
//or
var config = new MapperConfiguration(cfg => cfg.CreateMap<Order, OrderDto>());
var mapper = config.CreateMapper();
// or
var mapper = new Mapper(config);
OrderDto dto = mapper.Map<OrderDto>(order);
// or
OrderDto dto = Mapper.Map<OrderDto>(order);
AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<StreetEvent, StreetEventDTO>()
.ForMember(dest => dest.EvtSrc, opt => opt.MapFrom(src => src.evt_src))
.ForMember(dest => dest.MapId, opt => opt.MapFrom(src => src.map_id))
);
var targetList = AutoMapper.Mapper.Map<List<StreetEventDTO>>(list);
获取使用下面封装的代码,暂时处理是使用, Mapper.AssertConfigurationIsValid(); 如果用更好的建议,以后在优化,暂时没有出现问题,如果你出现了问题,请私信我,谢谢。
Profile的用法
第一步
public class DemoProfile : Profile
{
protected override void Configure()
{
CreateMap<Users, UserDB>();
// 支持很多规则,这些规则很多 等待你慢慢发现
//AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<StreetEvent, StreetEventDTO>()
// .ForMember(dest => dest.EvtSrc, opt => opt.MapFrom(src => src.evt_src))
// .ForMember(dest => dest.MapId, opt => opt.MapFrom(src => src.map_id))
// );
}
}
//第二步
public class Configuration
{
public static void Configure()
{
Mapper.Initialize(cfg =>
{
cfg.AddProfile<Profiles.DemoProfile>();
//......
});
}
}
//第三部在Global中调用
AutoMapper.Configuration.Configure();
用AutoMapper来实现info与viewModel的相互转换,让AutoMapper在你的项目里飞一会儿
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper.Configuration;
namespace ItemDoc.Services.Mapping
{
/// <summary>
/// AutoMapper扩展
/// </summary>
public static class AutoMapExtensions
{
/// <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="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>
/// <returns></returns>
public static TDestination MapTo<TDestination>(this object source) where TDestination : new()
{
return MapTo(source, new TDestination());
}
/// <summary>
/// 将源集合映射到目标集合
/// </summary>
/// <typeparam name="TDestination">目标元素类型,范例:Sample,不要加List</typeparam>
/// <param name="source">源集合</param>
/// <returns></returns>
public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
{
return MapTo<List<TDestination>>(source);
}
/// <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);
var destinationType = GetObjectType(destination);
var map = GetMap(sourceType, destinationType);
if (map != null)
{
return Mapper.Map(source, destination);
}
lock (Sync)
{
Mapper.Reset();
map = GetMap(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);
});
Mapper.AssertConfigurationIsValid();
}
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)
{
Mapper.Initialize(config =>
{
config.CreateMap(sourceType, destinationType);
});
}
return Mapper.Configuration.FindTypeMapFor(sourceType, destinationType);
}
}
}
/// <summary>
/// 获取对象类型
/// </summary>
/// <param name="obj">对象</param>
/// <returns></returns>
private static Type GetObjectType(object obj)
{
var type = obj.GetType();
if ((obj is 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];
}
}
}
参考资料:
如果存在问题,请私信或者其他方式告知,谢谢
所有源码均在个人项目中开源,欢迎star