AutoMapper 值转换器(Value Converters)
值转换器是 类型转换器 和 值解析器 的结合体。类型转换器是全局范围的,这意味着任何时间你从类型 Foo
映射到类型 Bar
的时候,在任何映射中都会使用该类型转换器。而值转换器则是限定在单一映射中的,它接收源对象和目标对象,并解析出一个值映射到目标成员上。此外,值转换器还可以选择性地接收源成员信息。
简化语法如下:
- 类型转换器 =
Func<TSource, TDestination, TDestination>
- 值解析器 =
Func<TSource, TDestination, TDestinationMember>
- 成员值解析器 =
Func<TSource, TDestination, TSourceMember, TDestinationMember>
- 值转换器 =
Func<TSourceMember, TDestinationMember>
要在成员级别配置值转换器,可以这样做:
public class CurrencyFormatter : IValueConverter<decimal, string>
{
public string Convert(decimal source, ResolutionContext context)
=> source.ToString("c");
}
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Order, OrderDto>()
.ForMember(d => d.Amount, opt => opt.ConvertUsing(new CurrencyFormatter()));
cfg.CreateMap<OrderLineItem, OrderLineItemDto>()
.ForMember(d => d.Total, opt => opt.ConvertUsing(new CurrencyFormatter()));
});
如果源成员名称不匹配,你可以自定义源成员:
public class CurrencyFormatter : IValueConverter<decimal, string>
{
public string Convert(decimal source, ResolutionContext context)
=> source.ToString("c");
}
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Order, OrderDto>()
.ForMember(d => d.Amount, opt => opt.ConvertUsing(new CurrencyFormatter(), src => src.OrderAmount));
cfg.CreateMap<OrderLineItem, OrderLineItemDto>()
.ForMember(d => d.Total, opt => opt.ConvertUsing(new CurrencyFormatter(), src => src.LITotal));
});
如果你需要服务定位器 ( 依赖注入 ) 实例化值转换器,可以指定类型而非实例:
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Order, OrderDto>()
.ForMember(d => d.Amount, opt => opt.ConvertUsing<CurrencyFormatter, decimal>());
cfg.CreateMap<OrderLineItem, OrderLineItemDto>()
.ForMember(d => d.Total, opt => opt.ConvertUsing<CurrencyFormatter, decimal>());
});
如果你在运行时不知道类型或成员名称,可以使用接受 System.Type
和基于 string
的成员的各种重载方法:
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap(typeof(Order), typeof(OrderDto))
.ForMember("Amount", opt => opt.ConvertUsing(new CurrencyFormatter(), "OrderAmount"));
cfg.CreateMap(typeof(OrderLineItem), typeof(OrderLineItemDto))
.ForMember("Total", opt => opt.ConvertUsing(new CurrencyFormatter(), "LITotal"));
});
值转换器仅用于内存映射执行,它们不适用于 ProjectTo
查询扩展方法 。