Answers:
作为ValueInjecter的创建者,我可以告诉你我这样做是因为我想要简单而又非常灵活的东西
我真的不喜欢写太多或写很多monkey code
类似的东西:
Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.
ValueInjecter 类似于mozilla,带有其插件,您可以创建ValueInjections并使用它们
有内置的用于扁平化,非扁平化的注入,还有一些旨在继承
并且它以方面类型的方式工作得更多,您不必指定所有属性为1对1,而是可以执行以下操作:
从源中获取所有以“ Id”结尾的int属性,转换值并将每个属性设置为源对象中具有相同名称的一个属性,其名称不带Id后缀,并且其类型是从Entity继承的,诸如此类
所以一个明显的区别是,ValueInjecter即使在具有展平和展平的Windows窗体中也可以使用,这就是它的灵活性
(从对象映射到窗体控件,然后再返回)
Automapper,不能在Windows窗体中使用,没有展开,但是它具有诸如集合映射之类的好东西,因此,如果需要ValueInjecter使用它,您可以执行以下操作:
foos.Select(o => new Bar().InjectFrom(o));
您还可以使用ValueInjecter来映射匿名和动态对象
差异:
自动映射器为每种映射可能性创建配置CreateMap()
从任何对象到任何对象的valueinjecter注入(在某些情况下,从对象到valuetype的注入)
automapper已构建了flattening,仅适用于简单类型或相同类型,并且没有unflattening
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(),其名称和类型相同;除此以外,您还可以使用单独的映射逻辑/规则创建自定义值注入,更像是方面,例如从Foo类型的所有道具到Bar类型的所有道具
<pedant>
看起来很酷,但也许应该是ValueInjectOr?</pedant>
由于我从未使用过任何其他工具,因此我只能谈论AutoMapper。我在构建AutoMapper时有一些目标:
如果您想做这些事情,AutoMapper会非常适合您。AutoMapper不好的事情是:
原因是我从来不需要做这些事情。在大多数情况下,我们的实体没有设置器,没有公开集合等,因此这就是为什么它不存在的原因。我们使用AutoMapper展平到DTO并从UI模型映射到命令消息等。那对我们真的非常有效。
我尝试了两者,并且更喜欢ValueInjecter,因为它是如此简单:
myObject.InjectFrom(otherObject);
我绝大多数的注射需求都知道这些。它不可能比这更简单和优雅。
this object
扩展方法在那里?
InjectFrom()
扩展方法。
这也是我一直在研究的一个问题,就我的用例而言,这似乎是价值注入者的不二之选。它不需要事先设置即可使用(我猜可能会影响性能,尽管如果实施得当,它可以缓存映射以供将来调用,而不是每次都反映出来),因此您无需在使用它们之前预先定义任何映射。
但是最重要的是,它允许反向映射。现在我可能在这里丢失了一些东西,因为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来说没有价值吗?)
但是,如果要确定的是您要使用的这种模式,那么我的投票是按国家英里来衡量的。