每次我在StackOverflow上寻找AutoMapper内容时,我都在阅读有关ValueInjecter的内容。
有人可以告诉我们它们之间的优缺点(性能,功能,API使用,可扩展性,测试)吗?
答案 0 :(得分:170)
作为ValueInjecter的创建者,我可以告诉你我之所以这样做是因为我想要一些简单且非常灵活的
我真的不喜欢写很多或写很多monkey code
喜欢:
Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.
ValueInjecter是像mozilla一样的插件,你创建了ValueInjections并使用它们
内置注射用于扁平化,不平整,以及一些旨在被遗传的注射
它在方面类型中工作得更多,您不必指定所有属性1对1,而是执行以下操作:
从源名称以“Id”结尾的所有int属性,转换值并将每个属性设置为源对象中具有相同名称但没有Id后缀的属性,并且它的类型继承自Entity,stuff像那样
所以有一个明显的区别,即使在具有展平和不平整的Windows窗体中也使用了ValueInjecter,这是多么灵活
(从对象映射到表单控件并返回)
Automapper,在Windows窗体中不可用,没有任何缺陷,但它有很好的东西,比如集合映射,所以万一你需要使用ValueInjecter,你只需做类似的事情:
foos.Select(o => new Bar().InjectFrom(o));
您还可以使用ValueInjecter从匿名和动态对象进行映射
<强>差异:强>
automapper为每个映射可能性创建配置CreateMap()
valueinjecter从任何对象注入任何对象(也有从对象注入到valuetype的情况)
automapper已经构建了扁平化,仅适用于简单类型或来自相同类型,并且没有不平整
valueinjecter只有在您需要的时候才会target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
如果您希望从Foo.Bar.Name of type String
到FooBarName of type Class1
继承FlatLoopValueInjection并指定此
默认情况下,automapper映射具有相同名称的属性,其余的则必须逐个指定,并执行Prop1.Ignore(),Prop2.Ignore()等内容。
valueinjecter有一个默认的注入.InjectFrom(),用于执行具有相同名称和类型的属性;对于其他一切,您使用单独的映射逻辑/规则创建自定义值注入,更像是方面,例如从Type Foo的所有道具到所有类型Bar的道具
答案 1 :(得分:59)
由于我从未使用过任何其他工具,因此我只能谈论AutoMapper。我在构建AutoMapper时考虑了几个目标:
如果您想要做这些事情,AutoMapper可以很好地为您服务。 AutoMapper表现不佳的事情是:
原因是我从来不需要做这些事情。在大多数情况下,我们的实体没有设置器,不暴露集合等,所以这就是为什么它不在那里。我们使用AutoMapper来展平DTO并从UI模型映射到命令消息等。这就是它真正适用于我们的地方。
答案 2 :(得分:55)
我尝试了两种并且更喜欢ValueInjecter,因为它很简单:
myObject.InjectFrom(otherObject);
对于我的绝大部分注射需求,我们都知道这一点。它不可能比这更简单和优雅。
答案 3 :(得分:27)
这是我一直在研究的一个问题,对于我的用例,它似乎是值得注意的。它不需要使用先前的设置(可能会达到性能我猜,虽然如果巧妙地实现它可以缓存未来调用的映射而不是每次反映),所以在使用它们之前不需要预先定义任何映射。
然而,最重要的是,它允许反向映射。现在我可能在这里遗漏了一些东西,因为Jimmy提到他没有看到必要的用例,所以也许我的模式有问题,但我的用例是我正在从我的ORM创建一个ViewModel对象。然后我在我的网页上显示这个。一旦用户完成,我将ViewModel作为httppost返回,如何将其转换回原始的ORM类?我很想知道使用automapper的模式。使用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有价值吗?)
但是,如果这个模式是你想要使用的模式,那么我的投票就是一个国家英里的价值。