AutoMapper vs ValueInjecter
每次我在StackOverflow上寻找AutoMapper的东西时,我正在读一些关于ValueInjecter的内容 。
有人可以告诉我他们之间的利弊(性能,function,API使用,可扩展性,testing)?
作为ValueInjecter的创造者,我可以告诉你,我做到了,因为我想要一些简单而又非常灵活的东西
我真的不喜欢写很多或者写很多monkey code
比如:
Prop1.Ignore, Prop2.Ignore etc. CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.
ValueInjecter 就像是Mozilla的插件,你创buildValueInjections并使用它们
有扁平化,解冻和一些打算inheritance的内置注射
它的工作方式更多,你不需要指定所有的属性1对1,而是像下面这样做:
从名称以“Id”结尾的源代码获取所有的int属性,转换该值并将其设置为源对象中具有相同名称而不带有Id后缀的属性,并且其types是从Entityinheritance的,类似这样的东西
所以一个明显的区别就是,ValueInjecter甚至用于窗体的扁平化和解压,这就是多么的灵活
(从对象映射到表单控件并返回)
Automapper,不能在Windows窗体中使用,不会失败,但它具有像集合映射这样的好东西,所以如果您需要使用ValueInjecter,只需执行以下操作:
foos.Select(o => new Bar().InjectFrom(o));
您还可以使用ValueInjecter来映射匿名和dynamic对象
不同之处:
-
automapper为每个映射可能性创buildconfigurationCreateMap()
-
valueinjecter从任何对象注入任何对象(也有情况下,当您从对象注入到valueType)
-
automapper具有flattening内置它,只为简单的types或从相同的types,它不具有unflattening
-
valueinjecter只有当你需要它你做
target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
,如果你想从Foo.Bar.Name of type String
到FooBarName of type Class1
你inheritanceFlatLoopValueInjection并且指定这个 -
默认情况下,automapper映射同名的属性,其余的你必须逐一指定,做一些像Prop1.Ignore(),Prop2.Ignore()等
-
valueinjecter有一个默认注入.InjectFrom(),它执行具有相同名称和types的属性; 对于所有其他的东西,你用单独的映射逻辑/规则创build自定义的值注入,更像是方面,例如从typesFoo的所有道具到types为Bar的所有道具
由于我从来没有使用任何其他工具,我只能谈论AutoMapper。 为了构buildAutoMapper,我有几个目标:
- 支持扁平DTO对象
- 支持明显的场景(集合,枚举等)
- 能够轻松validationtesting中的映射
- 允许边界情况下从其他地方parsing值(自定义types – >types映射,个人成员映射,和一些非常疯狂的边缘案例)。
如果你想做这些事,AutoMapper对你来说工作的很好。 事情AutoMapper不好做的是:
- 填充现有的对象
- Unflattening
原因是我从来不需要做这些事情。 在大多数情况下,我们的实体没有制定者,不公开collections等,所以这就是为什么它不在那里。 我们使用AutoMapper将其平面化为DTO,并从UI模型映射到命令消息等。 这就是它的工作原理,非常适合我们。
我尝试了两种方法,都比较喜欢ValueInjecter,因为它非常简单:
myObject.InjectFrom(otherObject);
这就是我所需要的大部分注射剂的知识。 它不可能变得比这更简单和优雅。
这也是我一直在研究的一个问题,对于我的用例来说,这似乎是值得注意的事情。 它不需要事先设置使用(可能会达到我想要的性能,但如果巧妙地实现它可以caching将来调用的映射,而不是每次反映),所以在使用它们之前不需要预先定义任何映射。
但最重要的是,它允许反向映射。 现在我可能会错过这里的东西,因为吉米提到他没有看到必要的用例,所以也许我的模式是错的,但我的用例是我从我的ORM创build一个ViewModel对象。 然后我在我的网页上显示这个。 一旦用户完成,我将ViewModel作为一个httppost重新获得,它是如何转换回原始的ORM类的? 我很想用automapper知道这个模式。 使用ValueInjector它是微不足道的,它甚至会不稳定。 例如创build一个新的实体
由entityframework(模型第一)创build的模型:
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(我可以用validation器来装饰):
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没有任何价值?)
但是,如果这个模式被认为是你想要使用的模式,那么我的投票是一个国家英里的价值观。