AutoMapper vs ValueInjecter

Каждый раз, когда я ищу AutoMapper материал в StackOverflow, я что-то читаю ValueInjecter.

Может ли кто-нибудь сказать мне плюсы и минусы между ними (производительность, функции, использование API, расширяемость, тестирование)?

Ответ 1

как создатель ValueInjecter, могу сказать, что я сделал это, потому что мне хотелось что-то просто и очень гибко

Мне действительно не нравится писать много или писать много monkey code, например:

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

ValueInjecter - это что-то как mozilla с плагинами, вы создаете ValueInjections и используете их

имеются встроенные инъекции для выравнивания, unflattening и некоторые, которые предназначены для наследования

и он больше работает в аспекте типа, вам не нужно указывать все свойства 1-к-1, вместо этого вы делаете что-то вроде:

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

, поэтому одно очевидное отличие: ValueInjecter используется даже в формах Windows с выравниванием и unflattening, что гибкость

(отображение элементов управления формой и формой)

Automapper, не пригодный для использования в формах Windows, без unflatenning, но у него есть хорошие вещи, такие как сопоставление коллекций, поэтому в случае необходимости с ValueInjecter вы просто делаете что-то вроде:

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

вы также можете использовать ValueInjecter для отображения из анонимных и динамических объектов

различия:

  • automapper создает конфигурацию для каждой возможности отображения CreateMap()

  • значение инжектора вводит из любого объекта в какой-либо объект (также есть случаи, когда вы вводите объект из объекта valuetype)

  • automapper имеет сплющенное построение и только для простых типов или одного и того же типа, и он не имеет unflattening

  • valueinjecter, только если вам это нужно, target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection> и если вы хотите от Foo.Bar.Name of type String до FooBarName of type Class1, вы наследуете FlatLoopValueInjection и указываете это

  • autapper сопоставляет свойства с одинаковым именем по умолчанию, а для остальных вы должны указывать один за другим и делать такие вещи, как Prop1.Ignore(), Prop2.Ignore() и т.д.

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

Ответ 2

Поскольку я никогда не использовал ни один из других инструментов, я могу говорить только об AutoMapper. Для создания AutoMapper у меня было несколько целей:

  • Поддержка выравнивания до немых объектов DTO
  • Поддержка очевидных сценариев из коробки (коллекции, перечисления и т.д.).
  • Уметь легко проверять сопоставления в тесте
  • Разрешить краевые случаи для разрешения значений из других мест (настраиваемое type- > type mapping, индивидуальное сопоставление элементов и некоторые действительно сумасшедшие случаи).

Если вы хотите сделать это, AutoMapper отлично работает для вас. Вещи AutoMapper не очень хорошо:

  • Заполнение существующих объектов
  • Unflattening

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

Ответ 3

Я попробовал оба и предпочел ValueInjecter, потому что это так просто:

myObject.InjectFrom(otherObject);

Это все, что нужно знать для подавляющего большинства моих потребностей в инъекциях. Он не может быть более простым и элегантным, чем это.

Ответ 4

Это вопрос, который я тоже изучал, и для моего варианта использования кажется, что у него снижается значение инжектора. Он не требует предварительной настройки для использования (может показаться, что это может повлиять на производительность, хотя, если она реализована, она может кэшировать сопоставления будущих вызовов, а не отражать каждый раз), поэтому вам не нужно заранее определять какие-либо сопоставления перед их использованием.

Самое главное, однако, это позволяет обратное отображение. Теперь у меня может быть что-то упущено, поскольку Джимми упоминает, что он не видит случая, когда это необходимо, поэтому, возможно, у меня неправильный шаблон, но мой вариант использования заключается в том, что я создаю объект 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; }
}

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

На мой взгляд, это не намного проще, чем это?

(Таким образом, возникает вопрос: что не так с шаблоном, с которым я сталкиваюсь (и, похоже, многие другие делают это), что его не видно как значение для AutoMapper?)

Однако, если этот шаблон как сокращенный, тот, который вы хотите использовать, тогда мой голос - это значение инжектора по сельской миле.