AutoMapper 枚举映射
内置的枚举映射器不可配置,只能被替换。作为替代方案,AutoMapper 在一个独立的包 AutoMapper.Extensions.EnumMapping 中支持基于约定的枚举值映射功能。
使用方法
对于 CreateMap 方法,这个库提供了一个 ConvertUsingEnumMapping 方法。此方法会添加从源枚举到目标枚举值的所有默认映射。
如果你想更改某些映射,则可以使用 MapValue 方法。这是一个可链式调用的方法。
默认情况下,枚举值按值(明确地说是:MapByValue())映射,但也可以通过调用 MapByName() 来按名称映射。
using AutoMapper.Extensions.EnumMapping;
public enum Source
{
Default = 0,
First = 1,
Second = 2
}
public enum Destination
{
Default = 0,
Second = 2
}
internal class YourProfile : Profile
{
public YourProfile()
{
CreateMap<Source, Destination>()
.ConvertUsingEnumMapping(opt => opt
// 可选:.MapByValue() 或 MapByName(),如果不进行配置,默认使用 MapByValue
.MapValue(Source.First, Destination.Default)
)
.ReverseMap(); // 支持从 Destination 到 Source 的映射,包括 ConvertUsingEnumMapping 的自定义映射
}
}
...
默认约定
包 AutoMapper.Extensions.EnumMapping 会将源类型的所有值映射到目标类型,如果这两个枚举类型具有相同的值(或按名称或按值)。所有没有目标等价物的源枚举值,在启用 EnumMappingValidation 时,将会抛出异常。
ReverseMap 约定
对于 ReverseMap 方法,使用的约定与默认映射相同,但它也会尊重可能的枚举值映射覆盖。
确定反向覆盖的步骤如下:
为
Source到Destination创建映射(使用默认约定),包括自定义覆盖。为
Destination到Source创建映射(使用默认约定),不包括自定义覆盖(需要确定)。步骤 1 中创建的映射将用于确定
ReverseMap的覆盖。因此,映射将按Destination值分组。3a) 如果有匹配的 `Source` 值对应于 `Destination` 值,则优先选择该映射,不需要覆盖。可能存在一个
Destination值对应多个通过覆盖映射指定的Source值。我们必须确定哪个
Source值将成为当前Destination值(现在是新的Source值)的新Destination。对于每个按
Destination值分组的Source值:3b) 如果 `Source` 枚举值在 `Destination` 枚举类型中不存在,则该映射无法反转。 3c) 如果有不是步骤1中映射部分的 `Source` 值,则该映射无法反转。 3d) 如果 `Source` 值未被选项b和c排除,则该 `Source` 值就是新的 `Destination` 值。步骤 3 中确定的所有覆盖将应用于步骤 2 中的映射。
最后,提供给
ReverseMap方法的自定义映射将被应用。
测试
AutoMapper 提供了验证类型映射的便捷工具。这个包添加了一个额外的 EnumMapperConfigurationExpressionExtensions.EnableEnumMappingValidation 扩展方法,以扩展现有的 AssertConfigurationIsValid() 方法来同时验证枚举映射配置。
为了启用枚举映射配置的测试:
public class MappingConfigurationsTests
{
[Fact]
public void WhenProfilesAreConfigured_ItShouldNotThrowException()
{
// Arrange
var config = new MapperConfiguration(configuration =>
{
configuration.EnableEnumMappingValidation();
configuration.AddMaps(typeof(AssemblyInfo).GetTypeInfo().Assembly);
});
// Assert
config.AssertConfigurationIsValid();
}
}
抠丁客
