自定义类型转换器

说明

当源类型与目标类型类型不一致,AutoMapper无法自动完成转换(例如stringint/DateTime/Type),直接映射会抛出异常,这时就需要自定义类型转换器

//源类:全部字段都是字符串
public class Source
{
    public string Value1 { get; set; }
    public string Value2 { get; set; }
    public string Value3 { get; set; }
}

//目标类:字段类型分别是int、DateTime、Type
public class Destination
{
    public int Value1 { get; set; }
    public DateTime Value2 { get; set; }
    public Type Value3 { get; set; }
}Code language: JavaScript (javascript)

直接映射Source→Destination会报错,AutoMapper不知道string怎么转为int、DateTime、Type。

ConvertUsing 的3种重载

//方式1:传入lambda/普通函数,适合简单转换
void ConvertUsing(Func<TSource, TDestination> mappingFunction);

//方式2:传入转换器实例
void ConvertUsing(ITypeConverter<TSource, TDestination> converter);

//方式3:传入转换器类型,AutoMapper内部实例化
void ConvertUsing<TTypeConverter>() where TTypeConverter : ITypeConverter<TSource, TDestination>;Code language: JavaScript (javascript)

ITypeConverter 接口

public interface ITypeConverter<in TSource, TDestination>
{
    TDestination Convert(TSource source, TDestination destination, ResolutionContext context);
}Code language: PHP (php)

示例代码

①实现自定义转换器
//string → DateTime转换器
public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
{
    public DateTime Convert(string source, DateTime destination, ResolutionContext context)
    {
        return System.Convert.ToDateTime(source);
    }
}

//string → Type转换器
public class TypeTypeConverter : ITypeConverter<string, Type>
{
    public Type Convert(string source, Type destination, ResolutionContext context)
    {
        return Assembly.GetExecutingAssembly().GetType(source);
    }
}Code language: HTML, XML (xml)
②Mapper初始化配置
[Test]
public void Example()
{
    Mapper.Initialize(cfg =>
    {
        //方式1:直接使用Func,string→int
        cfg.CreateMap<string, int>().ConvertUsing(s => Convert.ToInt32(s));

        //方式2:传入转换器实例
        cfg.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());

        //方式3:传入转换器类型,AutoMapper帮我们new
        cfg.CreateMap<string, Type>().ConvertUsing<TypeTypeConverter>();

        //配置实体之间映射
        cfg.CreateMap<Source, Destination>();
    });
    Mapper.AssertConfigurationIsValid();

    //测试数据
    var source = new Source
    {
        Value1 = "5",
        Value2 = "01/01/2000",
        Value3 = "AutoMapperSamples.GlobalTypeConverters.GlobalTypeConverters+Destination"
    };

    //执行映射
    Destination result = Mapper.Map<Source, Destination>(source);
    result.Value3.ShouldEqual(typeof(Destination));
}Code language: JavaScript (javascript)

新版AutoMapper

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<string, int>().ConvertUsing(s => Convert.ToInt32(s));
    cfg.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
    cfg.CreateMap<string, Type>().ConvertUsing<TypeTypeConverter>();
    cfg.CreateMap<Source, Destination>();
});
IMapper mapper = config.CreateMapper();

var result = mapper.Map<Destination>(source);Code language: JavaScript (javascript)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注