ExpressMapper-映射/克隆InvalidCastException

本文关键字:InvalidCastException 克隆 映射 ExpressMapper- | 更新日期: 2023-09-27 18:25:37

我目前在使用EmitMapper的解决方案中面临性能问题。由于性能和它被积极维护的事实,我想将我的IMapper的实现更改为ExpressMapper。

我的问题归结为映射枚举以及不应直接强制转换枚举的事实,因为这将生成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引发异常:System.InvalidCastException:的强制转换无效"映射.Source.CustomerType"到"映射.Target.CustomerType".

在System.Convert.DefaultToType(IConvertable值,Type targetType,IFormatProvider提供程序)System.Enum.System.IConvertible.ToType(类型,IFormatProviderprovider)在System.Convert.ChangeType(对象值,类型conversionType,IFormatProvider提供程序)位于的System.Convert.ChangeType(Object值,Type conversionType)位于的lambda_method(Closure、Customer、Customer)中的ExpressMapper.TypeMapperBase`2.MapTo(T src,TN dest)C: ''SourceCode''ExpressMapper''ExpressMapper NET40''TypeMapperBase.cs:line243在ExpressMapper.MappingServiceProvider.MapInternal[T,TN](Tsrc、TN dest、Boolean dynamicTrial)C: ''SourceCode''ExpressMapper''ExpressMapperNET40''MappingServiceProvider.cs:line 273ExpressMapper.MappingServiceProvider.MapInternal[T,TN](T src,TN dest,布尔dynamicTrial)NET40''MappingServiceProvider.cs:line 299ExpressMapper.MappingServiceProvider.Map[T,TN](T src)C: ''SourceCode''ExpressMapper''ExpressMapperNET40''MappingServiceProvider.cs:line 241ExpressMapper.Mapper.Map[T,TN](T src)C: ''SourceCode''ExpressMapper''ExpressMapper NET40''Mapper.cs:line 38
位于ExpressMapper.Extensions.ExpressmapperExtensions.Map[T,TN](Tsource)在C:''SourceCode''ExpressMapper''ExpressMapper中NET40''ExpressmapperExtensions.cs:line 11

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

我尝试了很多方法,包括实现CustomMapper以通用的方式映射枚举,但我没有中大奖。-我想知道是否唯一的出路是对ExpressMapper本身进行更改。

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

不会抛出InvalidCast。

ExpressMapper-映射/克隆InvalidCastException

Expressmapper通过使用IConvertable接口支持隐式转换,而这里的情况并非如此。我创建Github问题只是为了考虑它是否是实现的有效案例。到目前为止,你有很多选择,但最简单、最快的是:

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

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

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

相关文章:
  • 没有找到相关文章