AutoMapper null源值和自定义类型转换器,无法映射?

Mig*_*Mig 4 c# unit-testing automapper automapper-3

在AutoMapper中使用自定义类型转换器(ITypeConverter)时,如果源值为null,则似乎不会输入类型转换器代码,例如:

Mapper.CreateMap<string, Enum>().ConvertUsing<EnumConverter>();

Assert.AreEqual(Enum.Value1, Mapper.Map<Enum>("StringValue1"));
Assert.AreEqual(Enum.Value1, Mapper.Map<Enum>(null);
Assert.AreEqual(Enum.Value1, Mapper.Map<Enum?>(null);
Run Code Online (Sandbox Code Playgroud)

类型转换器看起来像:

public class EnumConvertor: ITypeConverter<string, Enum>
{
    public Enum Convert(ResolutionContext context)
    {
        string value = (string) context.SourceValue;

        switch (value)
        {
            case "StringValue2":
                return Enum.Value2;
            case "StringValue3":
                return Enum.Value3;
            case "StringValue1":
            default:
                return Enum.Value1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在最后两个案例中,结果如下:

Assert.AreEqual(Enum.Value1, Mapper.Map<Enum>(null);
Run Code Online (Sandbox Code Playgroud)

0 - 不是有效的枚举值

Assert.AreEqual(Enum.Value1, Mapper.Map<Enum?>(null);
Run Code Online (Sandbox Code Playgroud)

空值

从调试到测试,在这两种情况下,自定义TypeConverter永远不会被击中,似乎AutoMapper在映射器中有一些初始检查要映射而不需要求助于TypeConverter?

如果我指定一个空字符串(""),则测试按预期工作.

Jam*_*Hay 11

快速查看一下automapper的源代码,Mapper.Map(对象源)进行空检查.如果source为null,则返回T的默认值:

    public TDestination Map<TDestination>(object source, Action<IMappingOperationOptions> opts)
    {
        var mappedObject = default(TDestination);
        if (source != null)
        {
            var sourceType = source.GetType();
            var destinationType = typeof(TDestination);

            mappedObject = (TDestination)Map(source, sourceType, destinationType, opts);
        }
        return mappedObject;
    }
Run Code Online (Sandbox Code Playgroud)

  • 我也注意到了这一点.`TSource`和`TDestination`的重载没有这些检查,大概是因为已知Type可以检索该类型的任何映射,如果源对象是'null`则无法确定.它确实有意义,但有点不确定.因此正确的测试应该是`Assert.AreEqual(Enum.Value1,Mapper.Map <string,Enum>(null);`这解决了问题. (3认同)