AutoMapper vs ValueInjecter [закрито]


209

Кожен раз, коли я шукаю речі про AutoMapper в StackOverflow, я читаю щось про ValueInjecter .

Чи може хтось сказати мені плюси та мінуси між ними (продуктивність, функції, використання API, розширюваність, тестування)?


2
Ще один, про який я бачив багато згаданих - EmitMapper .
adrianbanks

1
А що з клеєм? glue.codeplex.com Виглядає також як чудовий проект, але я його ще не пробував. Я буду протягом наступного місяця, хоча. Я також бачив проект під назвою EmitMapper emitmapper.codeplex.com
Trygve

Дивіться статтю, що розповідає про ці два інструменти - devproconnections.com/development/…
Джордж Бірбіліс

Відповіді:


170

як творець ValueInjecter , я можу вам сказати, що я це зробив, бо хотів чогось простого і дуже гнучкого

Мені дуже не подобається писати чи писати багато monkey codeподібного:

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

ValueInjecter - це щось на кшталт mozilla з його плагінами, ви створюєте ValueInjections і використовуєте їх

є вбудовані ін'єкції для плоскостопості, розпушування та деякі, які мають бути успадковані

і це працює більше в аспектному способі , вам не потрібно вказувати всі властивості 1-до-1, натомість ви робите щось на кшталт:

візьміть усі властивості int з джерела, ім'я якого закінчується на "Id", перетворіть значення та встановіть кожне у властивість у вихідному об'єкті з тим самим іменем без суфікса Id, і його тип успадковується від Entity, такі речі

тому одна очевидна відмінність, ValueInjecter використовується навіть у формах Windows із сплющенням та розкручуванням, ось наскільки він гнучкий

(відображення від об'єкта до форми управління та назад)

Автоматизатор, не використовується у формах Windows, не розкручується, але у нього є хороші речі, як картографування колекцій, тож у випадку, якщо вам це потрібно з ValueInjecter, ви просто зробите щось на кшталт:

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

ви також можете використовувати ValueInjecter для картування з анонімних та динамічних об'єктів

відмінності:

  • автоматичне створення конфігурації для кожної можливості відображення CreateMap ()

  • valueinjecter вводить будь-який об'єкт у будь-який об'єкт (також є випадки, коли ви вводите з об'єкта в valuetype)

  • autompper має сплющений вбудований його, і тільки для простих типів або з одного типу, і він не має розстібання

  • valueinjecter тільки якщо вам це потрібно ви робите , target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection> і якщо ви хочете від Foo.Bar.Name of type Stringдо FooBarName of type Class1вам наслідувати FlatLoopValueInjection і вказати це

  • autompper відображає властивості з тим самим іменем за замовчуванням, а для решти вам потрібно вказати по черзі і виконувати такі речі, як Prop1.Ignore (), Prop2.Ignore () тощо.

  • valueinjecter має ін'єкцію за замовчуванням .InjectFrom (), яка виконує властивості з однаковою назвою та типом; для всього іншого ви створюєте свої власні значенняін'єкцій за допомогою індивідуальної логіки / правил відображення, більше подібних аспектів, наприклад, від усіх реквізитів Type Foo до всіх реквізитів типу Bar


5
Для бога кохання, будь ласка, скажіть мені, що ValueInjector може взяти глибокий графік ViewModel і зробити карту / з глибокого графіка Business Entity та зробити все, що точно так само, без роботи, і що мені потрібно лише вказати, як поводитися з тим, що відрізняється. Я сподівався, що AutoMapper додасть цю можливість, але вона ніколи не здійснилася, і я не встиг написати власний автовідповідач.
Кріс Марісіч

3
@Chris Marisic ви можете використовувати це робити, якщо ви маєте на увазі глибоке клонування, я зробив одну ін'єкцію одного разу, коли це робиться це рекурсивно, але не працює для колекцій властивостей valueinjecter.codeplex.com/Thread/View.aspx?ThreadId=236126 або ви можете зробити Flat ViewModel і використовувати вирівнювання і розпушування, це буде просто
Omu,

Субстанції ViewModel і доменів були б подібними, але різними, тому не чистим клоном. 90% властивостей зазвичай мають точний тип та ім'я, ViewModels часто закінчується SelectLists та предметами, пов’язаними з ними, які я хотів би ігнорувати, повертаючись до домену. Хоча в обох є колекції предметів.
Кріс Марісіч

27
<pedant>Виглядає круто, але, можливо, це має бути ValueInjectOr? </pedant>
Craig Stuntz

1
але чомусь це ер :)
Ому,

59

Оскільки я ніколи не використовував жодного з інших інструментів, я можу говорити лише про AutoMapper. Я мав на увазі кілька цілей для створення AutoMapper:

  • Підтримка згладжування тупих об'єктів DTO
  • Підтримка очевидних сценаріїв нестандартно (колекції, перерахування тощо)
  • Умійте легко перевірити відображення в тесті
  • Дозволити для крайових випадків для вирішення значень з інших місць (спеціальне відображення типу-> тип, окреме відображення членів і деякі справді шалені крайові випадки).

Якщо ви хочете зробити ці речі, AutoMapper працює для вас дуже добре. Те, що в AutoMapper не справляється, це:

  • Заповнення існуючих об'єктів
  • Розпушування

Причина в тому, що мені ніколи не потрібно було робити ці речі. Здебільшого у наших організацій немає сетерів, не виставляти колекції тощо, тому його там немає. Ми використовуємо AutoMapper для вирівнювання до DTO та мапу з моделей інтерфейсу для командування повідомленнями тощо. Ось де це працює насправді, дуже добре для нас.


1
@Jimmy Bogard Чи бачите ви, що заповнення існуючих об'єктів колись перетвориться на список функцій для AutoMapper?
Роман

Я не пробував ValueInjecter, але для того, що нам потрібно, автоматична машина дуже потужна.
richb01

Я думаю, що найважливіше тут - це перевіреність. Під час перейменування та реконструкції речей це величезна допомога.
Кугель

55

Я спробував обидва і віддаю перевагу ValueInjecter, тому що це так просто:

myObject.InjectFrom(otherObject);

Це все, що потрібно знати для переважної більшості моїх ін'єкційних потреб. Це, можливо, не може бути більш простим і елегантним, ніж це.


1
this objectметод розширення існує?
Кріс Марісіч

2
Як я міг роз'єднати свій код від ValueInjecter? Для мене, схоже, завжди є залежність від ValueInjecter, тобто в моєму веб-проекті, оскільки я використовую ValueInjecter (метод розширення) на даному об'єкті Прямо.
Рокіян

1
@Rookian чесно, це не турбота, про яку слід занадто багато думати. Ви можете залежати від інтерфейсу на зразок згаданого @Omu, тому якщо ви коли-небудь поміняєте картографи, ви можете зберегти певну роботу (напевно, не багато). Цей тип залежності занадто важко абстрагуватись, якщо ви не хочете потрапляти в повний AOP, який, на жаль, багато разів просто не змінюється, оскільки .NET не допомагає правильно підтримувати підтримку AOP. Тепер ви можете AOP відключити деякі карти, особливо якщо ви використовуєте MVC і записуєте фільтри дій, які обробляють відображення ViewModel / DomainModel.
Кріс Марісіч

13
Чому обгортка найкраще рішення? Єдине, що вам потрібно зробити, якщо ви хочете переключити Mapper - це самостійно реалізувати InjectFrom()метод розширення.
jgauffin

1
Я також спробував і те, і я віддаю перевагу AutoMapper. Я використовував його для невеликої частини моєї системи, де я збираю сутності з генерованими Linq2Sql класами. Просте відображення як StockTotalQuantity -> stock_size_quantity або UserId -> user_id працювало з AutoMapper за замовчуванням. Це не працювало з ValeInjecter навіть після додавання конвекції. Поки що дотримується AutoMapper.
Артур Кендзьор

27

Це питання я теж досліджував, і для мого використання, здається, це цінність рукоятки вниз. Він не потребує попередніх налаштувань для використання (можливо, може вразити ефективність, хоча, якщо розумно реалізовано, він може кешувати відображення майбутніх викликів, а не відображати кожен раз), тому вам не потрібно заздалегідь визначати будь-які відображення перед їх використанням.

Найголовніше, однак це дозволяє зворотне відображення. Зараз я, можливо, чогось тут не вистачаю, як Джиммі зазначає, що він не бачить випадку використання, де це необхідно, тому, можливо, у мене неправильний шаблон, але мій випадок використання полягає в тому, що я створюю об’єкт ViewModel з мого ORM. Потім я показую це на своїй веб-сторінці. Як тільки користувач закінчує, я повертаю ViewModel як httppost, як це повертається до початкових класів ORM? Мені б хотілося дізнатися схему за допомогою автомати. З ValueInjector це банально, і він навіть розкручується. наприклад, створення нової сутності

Модель, створена сутність фреймворку (перша модель):

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

Контролер ViewControl:

    //
    // 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
напевно, вам слід також задати це питання в окремому запитанні з тегом asp.net-mvc та кращими практиками, ViewModel ..., атм. Я не бачу жодної проблеми, якщо це добре працює для вас, але я впевнений, що хтось може мати різні думки
Ому,

Добре дізнавшись більше mvc. Зараз я можу відповісти на моє запитання. Спосіб оновлення оригінальної моделі, коли ви повертаєте модель переповненого перегляду, - це використання функції UpdateModel (), яку надає mvc.
DanH

1
UpdateModel () використовується для заповнення моделі, що представляє погляд, і це те саме, що робити Action (модель MyModelClasss)
Omu,

Щоправда, але якщо ви хочете мати окрему модель перегляду, наприклад, модель репозиторію, то вона може бути використана для заповнення того, що припущення відображення є тривіальним (і це часто є). Зрозуміло, якщо складніший ValueInjector прийде в свої власні.
DanH

1
Я думаю, міг би бути зроблений аргумент, що ви не повинні просто повертати свої властивості на вашу модель домену - ви повинні використовувати методи, які додають їй значення.
Майк Коул
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.