Cada vez que busco material de AutoMapper en StackOverflow, leo algo sobre ValueInjecter .
¿Alguien puede decirme los pros y los contras entre ellos (rendimiento, características, uso de API, extensibilidad, pruebas)?
Cada vez que busco material de AutoMapper en StackOverflow, leo algo sobre ValueInjecter .
¿Alguien puede decirme los pros y los contras entre ellos (rendimiento, características, uso de API, extensibilidad, pruebas)?
Respuestas:
Como creador de ValueInjecter , puedo decirte que lo hice porque quería algo simple y muy flexible
Realmente no me gusta escribir mucho o escribir muchos monkey code
como:
Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.
ValueInjecter es algo así como Mozilla con sus complementos, crea ValueInjections y los usa
hay inyecciones incorporadas para aplanar, desaplanar y algunas que están destinadas a ser heredadas
y funciona más en un aspecto de tipo , no tiene que especificar todas las propiedades 1 a 1, en su lugar, hace algo como:
toma todas las propiedades int de la fuente cuyo nombre termina con "Id", transforma el valor y establece cada una en una propiedad en el objeto fuente con el mismo nombre sin el sufijo Id y su tipo se hereda de Entity, cosas así
Entonces, una diferencia obvia, ValueInjecter se usa incluso en formularios de Windows con aplanamiento y no aplanamiento, así de flexible es
(mapeo del objeto para formar controles y viceversa)
Automapper, no se puede usar en formularios de Windows, no se deshace, pero tiene cosas buenas como el mapeo de colecciones, por lo que en caso de que lo necesite con ValueInjecter simplemente haga algo como:
foos.Select(o => new Bar().InjectFrom(o));
También puede usar ValueInjecter para mapear desde objetos anónimos y dinámicos
diferencias:
configuración de creación de automapper para cada posibilidad de mapeo CreateMap ()
inyectar valueinjecter de cualquier objeto a cualquier objeto (también hay casos en los que inyecta de objeto a valuetype)
automapper tiene un aplanamiento construido, y solo para tipos simples o del mismo tipo, y no tiene aplanamiento
valueinjecter sólo si lo necesita lo hace target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
y si quieres de Foo.Bar.Name of type String
que FooBarName of type Class1
se hereda FlatLoopValueInjection y especifica este
automapper asigna propiedades con el mismo nombre de forma predeterminada y para el resto debe especificar una por una, y hacer cosas como Prop1.Ignore (), Prop2.Ignore () etc.
valueinjecter tiene una inyección predeterminada .InjectFrom () que realiza las propiedades con el mismo nombre y tipo; para todo lo demás, cree sus inyecciones de valores personalizados con lógica / reglas de mapeo individuales, más aspectos similares, por ejemplo, desde todos los accesorios de Type Foo hasta todos los accesorios de tipo Bar
<pedant>
Parece genial, pero tal vez debería ser ValueInjectOr? </pedant>
Como nunca he usado ninguna de las otras herramientas, solo puedo hablar sobre AutoMapper. Tenía algunas metas en mente para construir AutoMapper:
Si desea hacer estas cosas, AutoMapper funciona muy bien para usted. Las cosas que AutoMapper no hace bien son:
La razón es que nunca he necesitado hacer estas cosas. En su mayor parte, nuestras entidades no tienen establecedores, no exponen colecciones, etc., por eso no está allí. Usamos AutoMapper para aplanar a DTO y mapear desde modelos de IU para mandar mensajes y similares. Ahí es donde funciona muy, muy bien para nosotros.
Probé ambos y prefiero ValueInjecter porque es muy simple:
myObject.InjectFrom(otherObject);
Eso es todo lo que hay que saber para la gran mayoría de mis necesidades de inyección. No puede ser más simple y elegante que esto.
this object
método de extensión allí?
InjectFrom()
método de extensión usted mismo.
Esta es una pregunta que también he estado investigando, y para mi caso de uso, parece ser un inyector de valor. No requiere una configuración previa para su uso (supongo que puede afectar el rendimiento, aunque si se implementa de manera inteligente podría almacenar en caché las asignaciones para invocaciones futuras en lugar de reflejar cada vez), por lo que no necesita predefinir ninguna asignación antes de usarlas.
Sin embargo, lo más importante es que permite el mapeo inverso. Ahora puede que me falte algo aquí, ya que Jimmy menciona que no ve ningún caso de uso cuando sea necesario, por lo que tal vez tenga el patrón incorrecto, pero mi caso de uso es que estoy creando un objeto ViewModel desde mi ORM. Luego muestro esto en mi página web. Una vez que el usuario finaliza, obtengo el ViewModel nuevamente como una publicación http, ¿cómo se vuelve a convertir a las clases ORM originales? Me encantaría conocer el patrón con automapper. Con ValueInjector es trivial e incluso se aplastará. por ejemplo, crear una nueva entidad
El modelo creado por el framework de entidad (modelo primero):
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; }
}
El ViewModel (que puedo decorar con validadores):
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; }
}
El 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();
}
}
En mi opinión, ¿no es mucho más simple que eso?
(Entonces esto plantea la pregunta, ¿qué tiene de malo el patrón con el que me encuentro (y parece que muchos otros lo hacen), que no se considera de valor para AutoMapper?)
Sin embargo, si este patrón, tal como se describe, es uno que desea utilizar, entonces mi voto es un inyector de valor por milla de país.