Ogni volta che sto cercando materiale AutoMapper su StackOverflow, sto leggendo qualcosa su ValueInjecter .
Qualcuno può dirmi i pro e i contro (prestazioni, funzionalità, utilizzo dell'API, estensibilità, test)?
Ogni volta che sto cercando materiale AutoMapper su StackOverflow, sto leggendo qualcosa su ValueInjecter .
Qualcuno può dirmi i pro e i contro (prestazioni, funzionalità, utilizzo dell'API, estensibilità, test)?
Risposte:
come creatore di ValueInjecter , posso dirti che l'ho fatto perché volevo qualcosa di semplice e molto flessibile
Non mi piace davvero molto scrivere o scrivere molti monkey code
simili:
Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.
ValueInjecter è qualcosa come mozilla con i suoi plugin, crei ValueInjections e li usi
ci sono iniezioni incorporate per l'appiattimento, non appiattimento e alcune che sono destinate ad essere ereditate
e funziona più in un tipo di aspetto , non è necessario specificare tutte le proprietà da 1 a 1, invece fai qualcosa del tipo:
prende tutte le proprietà int dalla sorgente il cui nome termina con "Id", trasforma il valore e imposta ciascuna su una proprietà nell'oggetto sorgente con lo stesso nome senza il suffisso Id e il suo tipo è ereditato da Entity, cose del genere
quindi un'ovvia differenza, ValueInjecter viene utilizzato anche in forme Windows con appiattimento e non appiattimento, ecco quanto è flessibile
(mappatura da oggetto a controlli forma e ritorno)
Automapper, non utilizzabile in Windows Form, senza appiattire, ma ha buone cose come la mappatura delle raccolte, quindi nel caso in cui tu ne abbia bisogno con ValueInjecter fai semplicemente qualcosa del tipo:
foos.Select(o => new Bar().InjectFrom(o));
puoi anche usare ValueInjecter per mappare da oggetti anonimi e dinamici
differenze:
automapper crea la configurazione per ogni possibilità di mappatura CreateMap ()
valueinjecter inietta da qualsiasi oggetto a qualsiasi oggetto (ci sono anche casi in cui si inietta da oggetto a tipo di valore)
automapper lo ha appiattito, e solo per tipi semplici o dello stesso tipo, e non ha appiattimento
valueinjecter solo se avete bisogno di fare target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection>
e se si vuole da Foo.Bar.Name of type String
a FooBarName of type Class1
si eredita FlatLoopValueInjection e specifica questa
automapper mappa le proprietà con lo stesso nome per impostazione predefinita e per il resto devi specificare una per una e fare cose come Prop1.Ignore (), Prop2.Ignore () ecc.
valueinjecter ha un'iniezione predefinita .InjectFrom () che esegue le proprietà con lo stesso nome e tipo; per tutto il resto crei le tue scelte di valore personalizzate con singole logiche / regole di mappatura, più aspetti simili, ad esempio da tutti gli oggetti di scena di tipo Foo a tutti gli oggetti di scena di tipo Bar
<pedant>
Sembra bello, ma forse dovrebbe essere ValueInjectOr? </pedant>
Dato che non ho mai usato nessuno degli altri strumenti, posso solo parlare di AutoMapper. Avevo in mente alcuni obiettivi per la creazione di AutoMapper:
Se vuoi fare queste cose, AutoMapper funziona molto bene per te. Le cose che AutoMapper non fa bene sono:
Il motivo è che non ho mai avuto bisogno di fare queste cose. Per la maggior parte, le nostre entità non hanno setter, non espongono raccolte, ecc. Ecco perché non è lì. Usiamo AutoMapper per appiattire i DTO e mappare dai modelli UI per comandare messaggi e simili. Ecco dove funziona davvero, molto bene per noi.
Ho provato entrambi e preferisco ValueInjecter perché è così semplice:
myObject.InjectFrom(otherObject);
Questo è tutto ciò che c'è da sapere per la stragrande maggioranza delle mie esigenze di iniezione. Non può essere più semplice ed elegante di così.
this object
metodo di estensione lì?
InjectFrom()
metodo di estensione da solo.
Questa è una domanda che ho studiato anche io, e per il mio caso d'uso, sembra essere più conveniente. Non richiede alcuna configurazione precedente da utilizzare (potrebbe influire sulle prestazioni, immagino, anche se se implementato in modo intelligente potrebbe memorizzare nella cache i mapping per invocazioni future anziché riflettere ogni volta), quindi non è necessario predefinire alcun mapping prima di utilizzarli.
Ancora più importante, tuttavia, consente la mappatura inversa. Ora potrei mancare qualcosa qui mentre Jimmy menziona che non vede alcun caso d'uso dove è necessario, quindi forse ho lo schema sbagliato, ma il mio caso d'uso è che sto creando un oggetto ViewModel dal mio ORM. Poi lo visualizzo sulla mia pagina web. Una volta che l'utente termina, visualizzo nuovamente ViewModel come httppost, come viene riconvertito nelle classi ORM originali? Mi piacerebbe conoscere il modello con automapper. Con ValueInjector è banale e non si appiattisce. ad es. creazione di una nuova entità
Il modello creato da entityframework (prima il modello):
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; }
}
Il ViewModel (che posso decorare con i validatori):
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; }
}
Il 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();
}
}
Secondo me, non è molto più semplice di così?
(Quindi questo fa sorgere la domanda, cosa c'è di sbagliato nel modello in cui mi imbatto (e sembra che molti altri lo facciano), che non è visto come di valore per AutoMapper?)
Tuttavia, se questo schema, come descritto, è quello che vuoi usare, allora il mio voto è più prezioso di un miglio di campagna.