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通过使用IConvertable接口支持隐式转换,而这里的情况并非如此。我创建Github问题只是为了考虑它是否是实现的有效案例。到目前为止,你有很多选择,但最简单、最快的是:
Mapper.Register<Mappings.Source.Customer, Mappings.Target.Customer>()
.Member(dst => dst.Type, src => (Mappings.Target.CustomerType)((int)src.Type));
在上面注册后,只需使用您的客户端映射代码。感谢您的宝贵意见!
更新:Expressmapper 1.8通过使用整数值作为枚举的映射条件来支持枚举映射。