当源属性未映射时强制抛出异常

本文关键字:抛出异常 映射 属性 | 更新日期: 2023-09-27 18:03:57

在AutoMapper 2.2.1中,是否有任何方法可以配置我的映射,以便当一个属性没有被显式忽略时,抛出异常?例如,我有以下类和配置:

public class Source
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }
}
public class Destination
{
    public int X { get; set; }
    public int Y { get; set; }
}

// Config
Mapper.CreateMap<Source, Destination>();

我从这个配置中收到的行为是设置了Destination.XDestination.Y属性。此外,如果我测试我的配置:

Mapper.AssertConfigurationIsValid();

那么我将不会收到映射异常。我希望发生的是抛出AutoMapperConfigurationException,因为Source.Z没有被显式忽略。

我希望它,以便我必须显式地忽略Z属性,以便AssertConfiguartionIsValid无异常地运行:

Mapper.CreateMap<Source, Destination>()
      .ForSourceMember(m => m.Z, e => e.Ignore());

目前,AutoMapper 不会抛出异常。我希望它抛出一个异常,如果我没有显式指定Ignore。我该怎么做呢?

当源属性未映射时强制抛出异常

下面是断言所有源类型属性都映射的方法:

public static void AssertAllSourcePropertiesMapped()
{
    foreach (var map in Mapper.GetAllTypeMaps())
    {
        // Here is hack, because source member mappings are not exposed
        Type t = typeof(TypeMap);
        var configs = t.GetField("_sourceMemberConfigs", BindingFlags.Instance | BindingFlags.NonPublic);
        var mappedSourceProperties = ((IEnumerable<SourceMemberConfig>)configs.GetValue(map)).Select(m => m.SourceMember);
        var mappedProperties = map.GetPropertyMaps().Select(m => m.SourceMember)
                                  .Concat(mappedSourceProperties);
        var properties = map.SourceType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
        foreach (var propertyInfo in properties)
        {
            if (!mappedProperties.Contains(propertyInfo))
                throw new Exception(String.Format("Property '{0}' of type '{1}' is not mapped", 
                                                  propertyInfo, map.SourceType));
        }
    }
}

它检查所有配置的映射,并验证每个源类型属性都定义了映射(要么映射,要么忽略)。

用法:

Mapper.CreateMap<Source, Destination>();
// ...
AssertAllSourcePropertiesMapped();

抛出异常

属性'Int32 Z'类型为'YourNamespace '。源'未映射

如果忽略该属性,则一切正常:

Mapper.CreateMap<Source, Destination>()
      .ForSourceMember(s => s.Z, opt => opt.Ignore());
AssertAllSourcePropertiesMapped();

新版本的AutoMapper有MapperConfiguration.AssertConfigurationIsValid()方法来验证所有的属性是否被映射。