目前,在使用EmitMapper的解决方案中,我面临着性能问题。我想将我的IMapper的实现更改为ExpressMapper,因为性能和它是积极维护的事实。
我的问题归结到映射Enums和枚举不应该直接转换的事实,因为这将生成一个InvalidCastException。
该解决方案在本质上是非常通用和动态的,我的主要ExpressMapper实现包含以下方法:
public TDestination Map<TSource, TDestination>(TSource src)
{
return src.Map<TSource, TDestination>();
}在不同名称空间中有两个相同的客户类,如下所示:
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:从“Mappings.Source.CustomerType”到“Mappings.Target.CustomerType”的无效强制转换。 在System.Convert.DefaultToType(IConvertible value,Type targetType,IFormatProvider provider) at System.Enum.System.IConvertible.ToType(Type type,IFormatProvider provider) at System.Convert.ChangeType(Object value,Type conversionType,IFormatProvider provider) at System.Convert.ChangeType(Object value,Type conversionType) at lambda_method(Closure,Customer,Customer ) at Closure.在C:\SourceCode\ExpressMapper\ExpressMapper,243 at ExpressMapper.MappingServiceProvider.MapInternalT,TN in C:\SourceCode\ExpressMapper\ExpressMapper,NET40\MappingServiceProvider.cs:line at ExpressMapper.MappingServiceProvider.MapInternalT,TN,273 in C:\SourceCode\ExpressMapper\ExpressMapper NET40\MappingServiceProvider.cs:line 299 at ExpressMapper.MappingServiceProvider.MapT,TN in C:\SourceCode\ExpressMapper\ExpressMapper NET40\MappingServiceProvider.cs:line 241 at ExpressMapper.Mapper.MapT,TN::\SourceCode\ExpressMapper\ExpressMapper NET40\Mapper.cs:line 38 在C中的ExpressMapper.Extensions.ExpressmapperExtensions.MapT,TN:\SourceCode\ExpressMapper\ExpressMapper NET40\ExpressmapperExtensions.cs:line 11
任何直接使用CustomerType枚举类型的解决方案都是无效的,因为它是一个动态系统,由具有各自对象图的可插拔组件组成,例如从一个CustomerProxy映射到一个客户组件(域对象)。
我尝试了许多方法,包括实现一个CustomMapper,以一种通用的方式映射枚举,但是我没有中奖。-我想知道唯一的出路是不是改变了ExpressMapper本身。
上述标准枚举之间映射的正确方法是: Mappings.Source.CustomerType -> int -> Mappings.Target.CustomerType
……不会抛出InvalidCast。
发布于 2015-12-04 06:12:05
Expressmapper通过使用IConvertible接口支持隐式转换,这里不是这种情况。我创建Github问题只是为了考虑到它是否是实现的有效案例。到目前为止,您有许多选择,但最简单和最快的是:
Mapper.Register<Mappings.Source.Customer, Mappings.Target.Customer>()
.Member(dst => dst.Type, src => (Mappings.Target.CustomerType)((int)src.Type));注册后,只需使用您的客户端映射代码。感谢您宝贵的意见!
UPDATE: Expressmapper1.8通过使用整数值作为枚举的映射条件来支持枚举映射。
https://stackoverflow.com/questions/34075459
复制相似问题