我目前在使用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。
答案 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支持枚举映射,使用整数值作为枚举的映射条件。