AutoMapper vs ValueInjecter [kapalı]


209

Her zaman StackOverflow AutoMapper şeyler arıyorum , ValueInjecter hakkında bir şey okuyorum .

Birisi bana aralarındaki artıları ve eksileri söyleyebilir mi (performans, özellikler, API kullanımı, genişletilebilirlik, test)?


2
Gördüğüm bir diğer şey de EmitMapper .
adrianbanks

1
Tutkal ne olacak? glue.codeplex.com Harika bir proje gibi görünüyor, ama henüz denemedim. Yine de gelecek ay boyunca yapacağım. Ayrıca EmitMapper adlı bir proje de gördüm emitmapper.codeplex.com
Trygve

Bu iki araç hakkında konuşan bir makaleye bakın - devproconnections.com/development/…
George Birbilis

Yanıtlar:


170

ValueInjecter'in yaratıcısı olarak, bunu yaptığımı söyleyebilirim çünkü basit ve çok esnek bir şey istedim

Gerçekten çok fazla yazmayı veya çok fazla yazmayı monkey codesevmiyorum:

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

ValueInjecter, eklentileriyle mozilla gibi bir şeydir , ValueInjections oluşturur ve bunları kullanırsınız.

düzleştirme, düzleştirme ve miras alınması amaçlanan yerleşik enjeksiyonlar vardır

ve en-boy oranıyla daha iyi çalışır , tüm özellikleri 1'e 1 olarak belirtmeniz gerekmez, bunun yerine şöyle bir şey yaparsınız:

adın "Id" ile biten tüm int özelliklerini alın, değeri dönüştürün ve her birini kaynak sonekini Id soneki olmadan aynı ada sahip bir özelliğe ayarlayın ve türü Entity'den devralınır, bunun gibi şeyler

bu yüzden bariz bir fark olan ValueInjecter, düzleştirici ve düzleştiricili pencerelerde bile kullanılır, bu ne kadar esnektir

(nesneden form denetimlerine ve geriye eşleme)

Automapper, Windows formlarında kullanılamaz, düzleştirilmez, ancak koleksiyon eşleme gibi iyi şeylere sahiptir, bu nedenle ValueInjecter ile ihtiyacınız olması durumunda şöyle bir şey yaparsınız:

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

anonim ve dinamik nesnelerden eşlemek için ValueInjecter'i de kullanabilirsiniz

farklar:

  • automapper her eşleme olasılığı için yapılandırma oluştur CreateMap ()

  • valueinjecter herhangi bir nesneden herhangi bir nesneye enjekte edilir (nesneden valueetype'a enjekte ettiğiniz durumlar da vardır)

  • automapper düzleştirdi ve sadece basit tipler için veya aynı tipte ve düzleştirici değil

  • valueinjecter yalnızca ihtiyacınız target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection> varsa Foo.Bar.Name of type Stringve FooBarName of type Class1sizden FlatLoopValueInjection kaynağını devralmak istiyorsanız bunu belirtin ve belirtin

  • automapper varsayılan olarak aynı ada sahip özellikleri eşler ve geri kalanı için tek tek belirtmeniz ve Prop1.Ignore (), Prop2.Ignore () vb.

  • valueinjecter, aynı ada ve türe sahip özellikleri yapan varsayılan bir .InjectFrom () yöntemine sahiptir; Diğer her şey için, özel değer enjeksiyonlarınızı, örneğin Foo Tipi tüm sahne alanlarından, Tip Bar'ın tüm sahne kısımlarına kadar , daha farklı yönlere sahip olan bireysel haritalama mantığı / kuralları ile oluşturursunuz.


5
Aşk tanrısı için lütfen bana ValueInjector derin bir grafik ViewModel alabilir ve derin bir grafik Business Entity için / harita ve hiçbir iş olmadan tam olarak aynı olan her şeyi harita ve sadece ne farklı işlemek için belirtmek gerekir. AutoMapper'ın bu özelliği ekleyeceğini umuyordum ama hiç gerçekleşmedi ve kendi otomatik eşlemcimi yazmak için zamanım olmadı.
Chris Marisic

3
@Crisris Marisic bunu kullanabilirsiniz, derin klonlama demek durumunda, bunu tekrar tekrar yapan bir kez yaptım ama koleksiyon özellikleri için çalışmaz valueinjecter.codeplex.com/Thread/View.aspx?ThreadId=236126 , ya da bir Flat ViewModel yapabilir ve düzleştirmeyi ve düzleştirmeyi kullanabilirsiniz, bu kolay olurdu
Omu

ViewModel ve Etki Alanı Varlıkları benzer ancak farklı olur, bu yüzden saf bir klon olmaz. Özelliklerin% 90'ı genellikle tam tür ve addır, ViewModels sıklıkla SelectLists ve etki alanına geri dönmeyi yoksaymak istediğim şeyler ile sonuçlanır. Her ikisinin de üzerinde nesne koleksiyonları olması muhtemeldir.
Chris Marisic

27
<pedant>Havalı görünüyor, ama belki ValueInjectOr olmalı? </pedant>
Craig Stuntz

1
ama nedense er :)
Omu

59

Diğer araçlardan daha önce hiç kullanmadığımdan sadece AutoMapper hakkında konuşabilirim. AutoMapper'ı oluşturmak için birkaç hedefim vardı:

  • Aptal DTO nesnelerine düzleştirme desteği
  • Kutusundan çıkan açık senaryoları destekleyin (koleksiyonlar, numaralandırmalar vb.)
  • Bir testteki eşlemeleri kolayca doğrulayabilme
  • Diğer yerlerden değerleri çözmek için kenar durumlara izin verin (özel tür-> tür eşleme, bireysel üye eşleme ve bazı gerçekten çılgın kenar durumlar).

Bunları yapmak istiyorsanız, AutoMapper sizin için çok iyi çalışır. AutoMapper'ın iyi yapmadığı şeyler şunlardır:

  • Mevcut nesneleri doldurma
  • Unflattening

Sebebi, bu şeyleri yapmak için hiç ihtiyacım olmadı. Çoğunlukla, varlıklarımızın ayarlayıcıları yoktur, koleksiyonları açığa çıkarmazlar, bu yüzden orada değildir. AutoMapper'ı DTO'ları düzleştirmek ve UI modellerinden mesajlar ve benzerlerine eşlemek için kullanırız. Burası bizim için gerçekten iyi çalışıyor.


1
@Jimmy Bogard Mevcut nesneleri doldurmanın, onu AutoMapper özellik listesine götürdüğünü görüyor musunuz?
Roman

ValueInjecter'ı denemedim, ancak ihtiyacımız olan şey için, automapper çok güçlü.
richb01

Bence buradaki en önemli şey doğrulanabilirlik. Bir şeyleri yeniden adlandırırken ve yeniden düzenlerken bu çok yardımcı olur.
Kugel

55

Her ikisini de denedim ve çok basit olduğu için ValueInjecter'ı tercih ettim:

myObject.InjectFrom(otherObject);

Enjeksiyon ihtiyacımın büyük çoğunluğu için bilmeniz gereken tek şey bu. Bundan daha basit ve zarif olamaz.


1
this objectorada uzatma yöntemi?
Chris Marisic

2
Kodumu ValueInjecter'den nasıl ayırabilirim? Benim için her zaman ValueInjecter yani web projemde bir bağımlılık var gibi görünüyor, çünkü verilen nesnede DOĞRUDAN ValueInjecter (uzantısı yöntemi) kullanın.
Rookian

1
@Rokian dürüstçe bu çok fazla düşünmek gerekir bir endişe değildir. @Omu gibi arayüze güvenebilirsiniz, böylece haritacıları değiştirirseniz biraz iş kaydedebilirsiniz (muhtemelen çok fazla değil). .NET tam olarak AOP desteği sağlamaya yardımcı olmadığından, ne yazık ki birçok kez geri alınamayan tam üflemeli AOP'ye girmek istemediğiniz sürece, bu tür bir bağımlılık soyutlamak için çok zordur. Şimdi, özellikle MVC kullanıyorsanız ve ViewModel / DomainModel eşlemesini işleyen Eylem Filtreleri yazarsanız, eşleştirmenin bir kısmını AOP yapabilirsiniz.
Chris Marisic

13
bir sarıcı neden en iyi çözümdür? Eşleştiriciyi değiştirmek istiyorsanız yapmanız gereken tek şey, InjectFrom()uzantı yöntemini kendiniz uygulamaktır.
jgauffin

1
İkisini de denedim ve AutoMapper'ı tercih ediyorum. Ben Linq2Sql oluşturulan sınıfları ile varlıkları eşlemek benim sistem küçük bir kısmı için kullandım. StockTotalQuantity -> stock_size_quantity veya UserId -> user_id olarak basit eşleme varsayılan olarak AutoMapper ile çalışmıştır. Convetion ekledikten sonra bile ValeInjecter ile çalışmadı. Şimdilik AutoMapper'a bağlı kalıyorum.
Artur Kędzior

27

Bu ben de araştırıyorum ve kullanım durumum için eller aşağı değer gibi görünüyor. Kullanmak için herhangi bir ön kurulum gerektirmez (akıllıca uygulanmışsa, eşlemeleri her seferinde yansıtmak yerine gelecekteki çağrılar için önbelleğe alabilmesine rağmen, sanırım performansa vurabilir), bu nedenle kullanmadan önce herhangi bir eşlemeyi önceden tanımlamanız gerekmez.

Ancak en önemlisi, ters haritalamaya izin verir. Şimdi burada bir şey eksik olabilir çünkü Jimmy gerekli olduğu yerde bir kullanım durumu görmediğinden bahsediyor, bu yüzden belki de desende yanlış var, ama benim kullanım durumum ORM'den bir ViewModel nesnesi oluşturduğum. Daha sonra bunu web sayfamda görüntülüyorum. Kullanıcı bittikten sonra ViewModel'i bir httppost olarak geri alıyorum, bu nasıl orijinal ORM sınıflarına geri dönüştürülür? Kalıbı automapper ile bilmek isterim. ValueInjector ile önemsizdir ve düzensizleşir. Örneğin, yeni bir varlık oluşturma

Varlık çerçevesi tarafından oluşturulan model (önce model):

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 (doğrulayıcılarla süsleyebileceğim):

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();
        }
    }

Bana göre bundan daha basit değil mi?

(Yani bu soruya yalvarır, ben bu içine koşmak desen ile yanlış olan (ve diğerleri yapmak gibi görünüyor), onun AutoMapper için değer olarak görülmüyor?)

Ancak, bu desen açıklandığı gibi, kullanmak istediğiniz modelse, oyum ülke miline göre değerlidir.


1
muhtemelen bunu asp.net-mvc ve en iyi uygulamalar, ViewModel ... ile etiketlenmiş ayrı bir soruda da sormalısınız. atm Sizin için iyi çalıştığı sürece herhangi bir sorun görmüyorum, ama eminim ki biri farklı görüşlere sahip olabilir
Omu

Peki daha fazla mvc öğrendim. Şimdi soruma cevap verebilirim. Doldurulmuş bir görünüm modelini geri aldığınızda orijinal modeli güncellemenin yolu, mvc'nin sağladığı UpdateModel () işlevini kullanmaktır.
DanH

1
UpdateModel (), görünümü temsil eden Modeli doldurmak için kullanılır ve Eylem (MyModelClasss modeli) ile
aynıdır

Doğru, ancak örneğin bir referans modeline ayrı bir görünüm modeline sahip olmak istiyorsanız, eşlemenin önemsiz (ve genellikle) olduğunu varsayarak doldurmak için kullanılabilir. Tabii daha karmaşık ValueInjector kendi başına gelirse.
DanH

1
Ben sadece kendi etki alanı modeli özelliklerinizi geri ayarlamanız gerektiğini argüman yapılabilir - buna anlam katan yöntemleri kullanmalısınız.
Mike Cole
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.