AutoMapper vs valueinjector

每次我在StackOverflow上寻找AutoMapper的东西时,我都在阅读有关ValueInjecter的东西。

谁能告诉我它们之间的优缺点(性能、特性、API使用、可扩展性、测试)?

54379 次浏览

作为ValueInjecter的创建者,我可以告诉你我这样做是因为我想要简单且非常灵活

我真的不喜欢写太多或写很多monkey code,比如:

Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.

valueinjector是就像mozilla的插件你创建valueinjection并使用它们

有一些内置的注入用于变平、变平,还有一些是打算被继承的

并且它在一种方面类型的方法中更有效,你不必1对1地指定所有属性,相反,你可以这样做:

从source中获取所有以“Id”结尾的int属性,转换值并将每个属性设置为源对象中具有相同名称但没有Id后缀的属性,它的类型从Entity继承,诸如此类

一个明显的区别是,valueinjector甚至在窗口表单中使用,有扁平化和不扁平化,这就是它的灵活性

(从对象映射到窗体控件并返回)

Automapper,不能在windows窗体中使用,没有unflatenning,但它有像集合映射这样的好东西,所以如果你需要它与valueinjector,你只需要做这样的事情:

foos.Select(o => new Bar().InjectFrom(o));

你也可以使用valueinjector来映射匿名动态对象

差异:

  • 自动为每个映射可能性创建配置

  • valueinjector从任何对象注入到任何对象(也有从对象注入到valuetype的情况)

  • Automapper有扁平化构建它,只对简单类型或从相同的类型,它没有不扁平化

  • valueinjector只有当你需要它时,才执行target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection> 如果你想要从Foo.Bar.Name of type StringFooBarName of type Class1,你继承FlatLoopValueInjection并指定这个

  • 默认情况下,automapper映射同名的属性,对于其余的属性,你必须逐个指定,并执行Prop1.Ignore(), Prop2.Ignore()等操作。

  • valueinjector有一个默认的注入.InjectFrom(),它使用相同的名称和类型的属性;对于其他所有东西,你创建你的自定义值注入与单独的映射逻辑/规则,更像方面,例如从类型Foo的所有道具到类型Bar的所有道具

我都试过了,更喜欢valueinjector,因为它太简单了:

myObject.InjectFrom(otherObject);

这就是我需要知道的绝大多数注射需求。没有比这更简单优雅的了。

由于我从未使用过其他工具,我只能谈谈AutoMapper。在构建AutoMapper时,我有几个目标:

  • 支持扁平化到哑DTO对象
  • 支持开箱即用的明显场景(集合、枚举等)
  • 能够在测试中轻松地验证映射
  • 允许使用边缘情况来解析来自其他地方的值(自定义类型->类型映射、单个成员映射和一些非常疯狂的边缘情况)。

如果你想做这些事情,AutoMapper非常适合你。AutoMapper做得不好的事情有:

  • 填充现有对象
  • Unflattening

原因是我从来不需要做这些事情。在大多数情况下,我们的实体没有setter,不公开集合,等等,这就是它不存在的原因。我们使用AutoMapper将图形化到dto,并从UI模型映射到命令消息等。这对我们来说非常非常有效。

这也是我一直在研究的一个问题,对于我的用例来说,它似乎是价值注入器。它不需要事先设置即可使用(我猜可能会影响性能,不过如果巧妙地实现,它可以为将来的调用缓存映射,而不是每次都反射),因此在使用任何映射之前不需要预先定义它们。

然而,最重要的是,它允许反向映射。现在,我可能在这里遗漏了一些东西,因为Jimmy提到他没有看到必要的用例,所以可能我的模式是错误的,但我的用例是从ORM创建一个ViewModel对象。然后我把它显示在我的网页上。一旦用户完成我得到的ViewModel回来作为一个httppost,这是如何转换回原来的ORM类?我想知道自动装置的模式。对于ValueInjector来说,这很简单,甚至会变得不平坦。例如:创建一个新的实体

由entityframework创建的模型(模型优先):

public partial class Family
{
public int Id { get; set; }
public string FamilyName { get; set; }


public virtual Address Address { get; set; }
}


public partial class Address
{
public int Id { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string TownCity { get; set; }
public string County { get; set; }
public string Postcode { get; set; }


public virtual Family Family { get; set; }
}

ViewModel(我可以用验证器装饰它):

public class FamilyViewModel
{
public int Id { get; set; }
public string FamilyName { get; set; }


public int AddressId { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressTownCity { get; set; }
public string AddressCounty { get; set; }
public string AddressPostcode { get; set; }
}

ViewController:

    //
// GET: /Family/Create


public ActionResult Create()
{
return View();
}


//
// POST: /Family/Create


[HttpPost]
public ActionResult Create(FamilyViewModel familyViewModel)
{
try
{
Family family = new Family();
family.InjectFrom<UnflatLoopValueInjection>(familyViewModel);
db.Families.Add(family);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}

在我看来,没有比这更简单的了吗?

(所以这就引出了一个问题,我遇到的模式有什么问题(似乎很多人都这样做),它不被视为有价值的AutoMapper?)

然而,如果你想使用描述的模式,那么我的投票是价值注入器。