ExpressMapper - 映射/克隆枚举 - InvalidCastException

时间:2015-12-03 20:22:42

标签: c# enums

我目前在使用EmitMapper的解决方案中遇到性能问题。我想将IMapper的实现更改为ExpressMapper,因为它有性能以及它是主动维护的。

我的问题归结为映射Enums以及不应直接转换枚举的事实,因为这将生成InvalidCastException。

该解决方案非常通用且具有动态性,我的主要ExpressMapper实现包含以下方法:

public TDestination Map<TSource, TDestination>(TSource src)
{
    return src.Map<TSource, TDestination>();
}

在不同的名称空间中有两个相同的Customer类,如下所示:

public class Customer
{
    public string Name { get; set; }

    public CustomerType Type { get; set; }
}

public enum CustomerType
{
    Company,
    Private,
    Government
}

我创建了一个简单的MSTest:

[TestClass]
public class ExpressMapperTest
{
    [TestMethod]
    public void SimpleMap()
    {
        // Arrange
        var myMapper = new MyMapper();
        Mappings.Source.Customer sourceCustomer = new Mappings.Source.Customer {
            Name = "John Doe",
            Type = Mappings.Source.CustomerType.Company
        };

        // Act
        var targetCustomer = myMapper.Map<Mappings.Source.Customer, Mappings.Target.Customer>(sourceCustomer);

        // Assert
        Assert.AreEqual(sourceCustomer.Name, targetCustomer.Name);
        Assert.AreEqual((int)sourceCustomer.Type, (int)targetCustomer.Type);
    }

}

结果是:

  

测试方法ExpressMapperTest.ExpressMapperTest.SimpleMap抛出   exception:System.InvalidCastException:来自的无效转换   'Mappings.Source.CustomerType'到'Mappings.Target.CustomerType'。

     

在System.Convert.DefaultToType(IConvertible值,Type targetType,   IFormatProvider提供商)   System.Enum.System.IConvertible.ToType(Type type,IFormatProvider   System.Convert.ChangeType(Object value,Type。)   conversionType,IFormatProvider provider)at   System.Convert.ChangeType(Object value,Type conversionType)at   lambda_method(关闭,客户,客户)at   ExpressMapper.TypeMapperBase`2.MapTo(T src,TN dest)in   C:\ SourceCode \ ExpressMapper \ ExpressMapper NET40 \ TypeMapperBase.cs:line   243在ExpressMapper.MappingServiceProvider.MapInternal [T,TN](T   src,TN dest,Boolean dynamicTrial)in   C:\源码\ ExpressMapper \ ExpressMapper   NET40 \ MappingServiceProvider.cs:第273行   ExpressMapper.MappingServiceProvider.MapInternal [T,TN](T src,TN dest,   布局dynamicTrial)在C:\ SourceCode \ ExpressMapper \ ExpressMapper中   NET40 \ MappingServiceProvider.cs:第299行   ExpressMapper.MappingServiceProvider.Map [T,TN](T src)in   C:\源码\ ExpressMapper \ ExpressMapper   NET40 \ MappingServiceProvider.cs:第241行   ExpressMapper.Mapper.Map [T,TN](T src)in   C:\ SourceCode \ ExpressMapper \ ExpressMapper NET40 \ Mapper.cs:第38行   在ExpressMapper.Extensions.ExpressmapperExtensions.Map [T,TN](T.   源代码)在C:\ SourceCode \ ExpressMapper \ ExpressMapper中   NET40 \ ExpressmapperExtensions.cs:第11行

直接使用CustomerType枚举类型的任何解决方案都是无效的,因为它是一个由可插入组件组成的动态系统,每个组件都有自己的对象图,例如,从CustomerProxy到Customer组件(域对象)。

我尝试过一系列方法,包括实现一个CustomMapper以通用的方式映射枚举,但是我还没有中奖。 - 我想知道前进的唯一方法是改变ExpressMapper本身。

如上所述在标准枚举之间进行映射的正确方法是: Mappings.Source.CustomerType - &gt; int - &gt; Mappings.Target.CustomerType

....不会抛出InvalidCast。

1 个答案:

答案 0 :(得分:4)

Expressmapper支持使用IConvertible接口进行隐式转换,但这不是这种情况。我创建了Github issue只是为了考虑它是否是有效的实施案例。 到目前为止,你有很多选择,但最简单,最快的是:

Mapper.Register<Mappings.Source.Customer, Mappings.Target.Customer>()
   .Member(dst => dst.Type, src => (Mappings.Target.CustomerType)((int)src.Type));

上面注册后,只需使用您的客户端映射代码。 感谢您的宝贵意见!

更新:Expressmapper 1.8支持枚举映射,使用整数值作为枚举的映射条件。