209

StackOverflow でAutoMapperのものを探しているたびに、 ValueInjecterについて何か読んでいます。

それらの間の長所と短所 (パフォーマンス、機能、API の使用、拡張性、テスト) を教えてもらえますか?

4

4 に答える 4

170

ValueInjecterの作成者として、シンプルで非常に柔軟なものが欲しかったので、私はそれをやったと言えます

私は本当に多くのことを書いたり、次のようなことをたくさん書いたりするのは好きではありませんmonkey code:

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

ValueInjecter は、プラグインを備えた mozilla のようなものです。ValueInjections を作成して使用します。

平坦化、非平坦化、および継承を目的とした組み込みのインジェクションがあります

また、 way のアスペクト タイプでより機能します。すべてのプロパティを 1 対 1 で指定する必要はありません。代わりに、次のようにします。

名前が「Id」で終わるソースからすべての int プロパティを取得し、値を変換して、Id サフィックスなしの同じ名前のソース オブジェクトのプロパティにそれぞれを設定し、そのタイプはエンティティから継承されます。

明らかな違いの 1 つは、ValueInjecter がフラット化と非フラット化を伴う Windows フォームでも使用されていることです。

(オブジェクトからフォーム コントロールへのマッピングとその逆)

Automapper、Windowsフォームでは使用できず、非平坦化はありませんが、コレクションマッピングなどの優れた機能を備えているため、ValueInjecterで必要な場合は、次のようにします:

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

ValueInjecter を使用して、匿名および動的オブジェクトからマップすることもできます

違い:

  • マッピングの可能性ごとに automapper が設定を作成する CreateMap()

  • valueinjecter inject from any object to any object (inject from object to valuetypeの場合もある)

  • オートマッパーにはフラット化が組み込まれており、単純な型または同じ型からのみ作成され、非平坦化はありません

  • valueinjecter は必要な場合にのみ実行しtarget.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection> 、必要な場合は FlatLoopValueInjection を継承Foo.Bar.Name of type StringしてFooBarName of type Class1これを指定します

  • automapper はデフォルトで同じ名前のプロパティをマップし、残りは 1 つずつ指定する必要があり、Prop1.Ignore()、Prop2.Ignore() などを実行します。

  • valueinjecter には、同じ名前とタイプのプロパティを実行するデフォルトの注入 .InjectFrom() があります。他のすべてについては、個々のマッピングロジック/ルールを使用してカスタム値注入を作成します。たとえば、Foo 型のすべての props から Bar 型のすべての props までの側面に似ています。

于 2011-01-12T20:38:07.270 に答える
59

私は他のツールを使用したことがないので、AutoMapper についてのみ話すことができます。AutoMapper を構築するにあたって、いくつかの目標を念頭に置いていました。

  • ダム DTO オブジェクトへのフラット化をサポート
  • すぐに使用できる明白なシナリオ (コレクション、列挙など) をサポートします。
  • テストでマッピングを簡単に検証できる
  • 他の場所からの値を解決するためのエッジ ケースを考慮します (カスタム型->型マッピング、個々のメンバー マッピング、およびいくつかの非常にクレイジーなエッジ ケース)。

これらのことをしたい場合は、AutoMapper が非常にうまく機能します。AutoMapper がうまくいかないことは次のとおりです。

  • 既存のオブジェクトを埋める
  • 非平坦化

その理由は、私がこれらのことをする必要がなかったからです. ほとんどの場合、エンティティにはセッターがなく、コレクションなども公開されていないため、存在しません。AutoMapper を使用して DTO にフラット化し、UI モデルからコマンド メッセージなどにマップします。それが私たちにとって本当に、本当にうまく機能するところです。

于 2011-03-30T02:10:02.577 に答える
55

I tried both and prefer ValueInjecter because it's so simple:

myObject.InjectFrom(otherObject);

That's all there is to know for the vast majority of my injection needs. It can't possibly get more simple and elegant than this.

于 2011-01-12T21:07:03.717 に答える
27

これは私も調査してきた質問であり、私の使用例では、valueinjecter のようです。使用するための事前のセットアップは必要ありません (パフォーマンスが低下する可能性がありますが、スマートに実装されていれば、毎回反映するのではなく、将来の呼び出しのためにマッピングをキャッシュできます)。そのため、使用する前にマッピングを事前に定義する必要はありません。

ただし、最も重要なことは、逆マッピングが可能であることです。ジミーが必要なユースケースを見ていないと述べているので、ここで何かが欠けている可能性があるため、パターンが間違っている可能性がありますが、私のユースケースは、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; }
}

ビューコントローラー:

    //
    // 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 にとって価値があるとは見なされていないという、私がこれに遭遇したパターンの何が問題なのかという疑問を生じさせます (そして、他の多くの人がそうしているようです)。)

ただし、説明されているこのパターンを使用したい場合、私の投票は 1 マイル単位の valueinjecter です。

于 2011-04-15T03:31:24.473 に答える