AutoMapper与ValueInjecter

Roo*_*ian 209 .net c# automapper object-object-mapping valueinjecter

每次我在StackOverflow上寻找AutoMapper时,我都在阅读有关ValueInjecter的内容.

有人能告诉我它们之间的优缺点(性能,功能,API使用,可扩展性,测试)吗?

Omu*_*Omu 170

作为ValueInjecter的创造者,我可以告诉你我这样做是因为我想要一些简单而灵活的东西

我真的不喜欢写很多或写很多monkey code像:

Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.
Run Code Online (Sandbox Code Playgroud)

ValueInjecter 类似于Mozilla的插件,你可以创建ValueInjections并使用它们

有内置注射用于扁平化,不平整,以及一些旨在被遗传的注射剂

并且它以方式类型的方式工作更多,您不必指定所有属性1对1,而是执行以下操作:

从源名称以"Id"结尾的所有int属性,转换值并将每个属性设置为源对象中具有相同名称但没有Id后缀的属性,并且它的类型是从Entity继承的,类似的东西

所以有一个明显的区别,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 StringFooBarName of type Class1你继承FlatLoopValueInjection并指定此

  • 默认情况下,automapper会映射具有相同名称的属性,其余的则必须逐个指定,并执行Prop1.Ignore(),Prop2.Ignore()等操作.

  • valueinjecter有一个默认的注入.InjectFrom(),用于执行具有相同名称和类型的属性; 对于其他一切你用自己的映射逻辑/规则创建自定义值注入,更像是方面,例如从Type Foo的所有道具到所有类型Bar的道具

  • `<pedant>`看起来很酷,但也许它应该是ValueInjectOr?`</夫子>` (27认同)
  • 对于爱神,请告诉我,ValueInjector可以采用深度图ViewModel并映射到深层图形业务实体,并映射完全相同但没有工作的所有内容,并且我只需要指定如何处理不同的内容.我一直希望AutoMapper能够添加这个功能,但它从未实现,我没有时间编写自己的自动映射器. (5认同)
  • @Chris Marisic你可以用它做它,如果你的意思是深度克隆,我做了一次注射,有点这样递归,但不适用于集合属性http://valueinjecter.codeplex.com/Thread/View.aspx ?ThreadId = 236126,或者你可以做一个Flat ViewModel并使用flattening和unflattening,这很容易 (3认同)

Jim*_*ard 59

由于我从未使用过任何其他工具,因此我只能谈论AutoMapper.我有一些目标是构建AutoMapper:

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

如果您想要做这些事情,AutoMapper可以很好地为您服务.AutoMapper做得不好的事情是:

  • 填充现有对象
  • Unflattening

原因是我从来不需要做这些事情.在大多数情况下,我们的实体没有设置器,不暴露集合等,所以这就是为什么它不在那里.我们使用AutoMapper来展平DTO并从UI模型映射到命令消息等.这就是它真正起作用的地方,对我们来说非常好.


Adr*_*ore 55

我尝试过两者并且更喜欢ValueInjecter,因为它非常简单:

myObject.InjectFrom(otherObject);
Run Code Online (Sandbox Code Playgroud)

对于我的绝大多数注射需求而言,这就是所有需要知道的.它不可能比这更简单和优雅.

  • 为什么包装是最好的解决方案?如果要切换映射器,唯一需要做的就是自己实现`InjectFrom()`扩展方法. (13认同)
  • 我怎么能将我的代码与ValueInjecter分离?对我来说,似乎总是依赖于ValueInjecter,即在我的web项目中,因为我在给定对象DIRECTLY上使用ValueInjecter(扩展方法). (2认同)

Dan*_*anH 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; }
}
Run Code Online (Sandbox Code Playgroud)

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; }
}
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

在我看来,它并没有那么简单?

(所以这引出了一个问题,我遇到的模式是错的(似乎很多其他人都这么做),它不被认为对AutoMapper有价值吗?)

但是,如果这个模式被解释,是你想要使用的模式,那么我的投票就是一个国家英里的价值.