自动映射器的替代方案

除了 AutoMapper,还有哪些不同的框架可用于.NET 中的对象到对象映射

目前我们计划使用 AutoMapper,但是在完成这个框架之前,我们希望了解其他任何框架。

46971 次浏览

最近,我经历了一个类似的过程,试图找到一个能够真正覆盖我所有场景的映射器。我发现 ValueInjecter 是自动绘制程序、发射绘制程序以及其他一些 coendrix 程序中最好的。

我选择 ValueInjector 是因为它是最灵活的。我需要从实体映射到视图模型,从视图模型映射回实体,深度克隆客户-> 项目-> 项目,递归情况如 customer <-> 项目,以及添加/更新/删除子集合。

开箱即用的 ValueInjector 不支持这一点,但是它的框架具有足够的可扩展性,可以轻松地支持这一点。你可以在我发布在他们讨论论坛的会议上看到我的扩展点。

Http://valueinjecter.codeplex.com/discussions/274484

老问题了看看 Mapster。如果性能非常关键并且支持大多数 AutoMapper 场景,那么它比 AutoMapper (在我使用过的场景中是5-10X)快得多。永远记住要进行性能测试,因为结果因情况而异。
我们发布了一个适用于.Net 4.0/4.5/Core 的新3.x 版本,支持几个新特性,并且有很大的性能改进。

Http://www.nuget.org/packages/mapster/

Https://github.com/eswann/mapster

披露... 这是我的一个项目,是为高负载服务创建的自动映射器开始显示,作为我们的瓶颈之一。

如果你想“自己卷”..。 下面是 AutoMapper 的 Quickn 脏替代品(更容易调试问题 + 少一个项目依赖)

    public static List<TResult> QuickMapper<TSource, TResult>(IList<TSource> data) where TResult : new()
{
/*




N.B. 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% 的功能。这些工具通常经过了很好的测试,经过实践,我们喜欢越来越多地使用它们,然后我们开始使用它们的其他花哨的可能性。升级产品总是有风险的,但这就是单元测试的目的。
此外,我还发现了一个看起来很有前途的新映射器: Hmapper。 我特别喜欢它的性能,它能够选择在映射过程中必须检索哪些子对象,以及它映射开放泛型类型的强类型方式。 到目前为止,这个映射器工作得很好,至少在我当前的项目中是这样的。 看看这里:

Http://www.codeproject.com/tips/1152752/h-mapper

例如,我们可以使用 Linq 指定子对象:

Mapper.Map<Class1, Class2>(source, x=>x.Subobject)

这样,我们就不必为详细信息创建 DTO 类,也不必为清单创建另一个类(轻量级)。

我觉得这很棒。

这是一个老问题,但现在还有 https://github.com/agileobjects/AgileMapper