Кожен раз, коли я шукаю речі про AutoMapper в StackOverflow, я читаю щось про ValueInjecter .
Чи може хтось сказати мені плюси та мінуси між ними (продуктивність, функції, використання API, розширюваність, тестування)?
Кожен раз, коли я шукаю речі про AutoMapper в StackOverflow, я читаю щось про ValueInjecter .
Чи може хтось сказати мені плюси та мінуси між ними (продуктивність, функції, використання API, розширюваність, тестування)?
Відповіді:
як творець 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
<pedant>
Виглядає круто, але, можливо, це має бути ValueInjectOr? </pedant>
Оскільки я ніколи не використовував жодного з інших інструментів, я можу говорити лише про AutoMapper. Я мав на увазі кілька цілей для створення AutoMapper:
Якщо ви хочете зробити ці речі, AutoMapper працює для вас дуже добре. Те, що в AutoMapper не справляється, це:
Причина в тому, що мені ніколи не потрібно було робити ці речі. Здебільшого у наших організацій немає сетерів, не виставляти колекції тощо, тому його там немає. Ми використовуємо AutoMapper для вирівнювання до DTO та мапу з моделей інтерфейсу для командування повідомленнями тощо. Ось де це працює насправді, дуже добре для нас.
Я спробував обидва і віддаю перевагу ValueInjecter, тому що це так просто:
myObject.InjectFrom(otherObject);
Це все, що потрібно знати для переважної більшості моїх ін'єкційних потреб. Це, можливо, не може бути більш простим і елегантним, ніж це.
this object
метод розширення існує?
InjectFrom()
метод розширення.
Це питання я теж досліджував, і для мого використання, здається, це цінність рукоятки вниз. Він не потребує попередніх налаштувань для використання (можливо, може вразити ефективність, хоча, якщо розумно реалізовано, він може кешувати відображення майбутніх викликів, а не відображати кожен раз), тому вам не потрібно заздалегідь визначати будь-які відображення перед їх використанням.
Найголовніше, однак це дозволяє зворотне відображення. Зараз я, можливо, чогось тут не вистачаю, як Джиммі зазначає, що він не бачить випадку використання, де це необхідно, тому, можливо, у мене неправильний шаблон, але мій випадок використання полягає в тому, що я створюю об’єкт 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?)
Однак, якщо ви хочете використовувати цю схему як розписану, то мій голос визначається за милю в країні.