AutoMapper的替代品
除了AutoMapper之外,.NET中的对象到对象映射有哪些不同的替代框架
目前我们正在计划使用AutoMapper,但在完成这个框架之前,我们想要了解其他任何框架。
EmitMapper, http: //emitmapper.codeplex.com/
ValueInjecter https://github.com/omuleanu/ValueInjecter
BLToolkit https://github.com/igor-tkachev/bltoolkit
而我的作业开发OoMapper https://github.com/hazzik/OoMapper
最近我也经历了一个类似的过程,试图find一个真正覆盖我所有场景的映射器。 我发现ValueInjecter是automapper,emitmapper和其他一些codeplex中最好的。
我selectValueInjector是因为它是最灵活的。 我需要从实体映射到视图模型,然后将视图模型映射回实体,在客户 – >项目 – >项目 – 客户 – >项目和递增/更新/删除子集合等recursion情况下进行深度克隆。
开箱即用的ValueInjector不支持这一点,但它的框架是可扩展的,足以支持这一点很容易。 您可以在我发布在他们的论坛上的这个会议中看到我的扩展点…
有许多select,如:
- EmitMapper
- AutoMapper
- ValueInjecter
- TinyMapper
- OoMapper
- Mapster
但是也可以使用Expressmapper 。 它很简单,它基于expression式树,作为手写代码工作,任何映射都在解决scheme中得到高度优化。 你也可以看看事实 – certificateExpressmapper和手写代码一样的基准 。 它具有与AutoMapper几乎相同的function,其他function将在未来版本中得到支持。 而且使用起来非常简单。
老问题,但看看在Mapster。 如果性能非常关键,并且支持大多数AutoMapper场景,则它比AutoMapper(在我使用的场景中为5-10X)快得多。 始终记住要进行性能testing,因为结果因场景而异。
我们已经放弃了一个适用于.Net 4.0 / 4.5 / Core的新的3.x版本,支持一些新的function,并且有很大的改进。
http://www.nuget.org/packages/Mapster/
https://github.com/eswann/Mapster
泄露…这是我的一个项目,创build一个高负载的服务,其中AutoMapper开始显示为我们的瓶颈之一。
如果你更喜欢“滚动自己的”…这是一个快速ñ脏的替代AutoMapper(位更容易debugging问题+ 1减less项目依赖)
public static List<TResult> QuickMapper<TSource, TResult>(IList<TSource> data) where TResult : new() { /* NB no DEEP copy - good for simple dto to View Model transfer etc ... classes will need to have a parameterless constructor 'where TResult : new()' by default - this will ignore cases where destination object does not have one of the source object's fields- common in ViewModels ... you could use a Dictionary<String,string> param to handle cases where property names don't marry up.. to use : List<Class2> lst2 = Helper.QuickMapper<Class1, Class2>(lst1).ToList(); */ var result = new List<TResult>(data.Count); PropertyDescriptorCollection propsSource = TypeDescriptor.GetProperties(typeof(TSource)); PropertyDescriptorCollection propsResult= TypeDescriptor.GetProperties(typeof(TResult)); TResult obj; Object colVal; string sResultFieldName = ""; string sSourceFieldName = ""; foreach (TSource item in data) { obj = new TResult(); for (int iResult = 0; iResult < propsResult.Count; iResult++) { PropertyDescriptor propResult = propsResult[iResult]; sResultFieldName = propResult.Name ; for (int iSource = 0; iSource < propsResult.Count; iSource++) { PropertyDescriptor propSource = propsSource [iSource ]; sSourceFieldName = propSource.Name; if (sResultFieldName == sSourceFieldName) { try { colVal = propSource.GetValue(item) ?? null; propResult.SetValue(obj, colVal); } catch (Exception ex) { string ss = "sResultFieldName = " + sResultFieldName + "\r\nsSourceFieldName = " + sSourceFieldName + "\r\n" + ex.Message + "\r\n" + ex.StackTrace; // do what you want here ... } } } } result.Add(obj); } return result; }
为什么不使用这样的工具,即使你只需要10%的function。 这些工具通常都经过了良好的testing和实践,我们喜欢越来越多地使用它们,然后我们开始使用他们其他的花哨的可能性。 升级产品总是有风险的,但这是unit testing的目的。
另外,我发现了一个看起来很有前景的新映射器: Hmapper 。 我特别喜欢它的性能,它能够select在映射过程中必须检索的子对象,以及强types映射开放genericstypes的方法。 至今在我目前的项目中,这个映射器运行良好。 看看这里:
http://www.codeproject.com/Tips/1152752/H-Mapper
例如,我们可以使用Linq指定子对象:
Mapper.Map<Class1, Class2>(source, x=>x.Subobject)
这样,我们不必创build一个DTO类的详细信息和另一个列表(重量轻)。
我觉得这很整齐。
这是一个老问题,但现在也有https://github.com/agileobjects/AgileMapper