Automapper è un "mappatore oggetto-oggetto" per .Net, che significa copiare oggetti da una classe in un'altra classe che rappresenta la stessa cosa.
Perché è mai utile? La duplicazione delle lezioni è mai utile / di buon design?
Automapper è un "mappatore oggetto-oggetto" per .Net, che significa copiare oggetti da una classe in un'altra classe che rappresenta la stessa cosa.
Perché è mai utile? La duplicazione delle lezioni è mai utile / di buon design?
Risposte:
Una rapida ricerca su Google ha rivelato questo esempio:
http://www.codeproject.com/Articles/61629/AutoMapper
mostrando un uso perfettamente valido di AutoMapper che sicuramente non è un esempio per un design scadente. In un'applicazione a più livelli, potresti avere oggetti nei tuoi dati o livello aziendale e a volte hai bisogno solo di un sottoinsieme degli attributi di tali oggetti dati o di una sorta di vista su di essi nel tuo livello UI. Quindi si crea un modello di vista che contiene oggetti con esattamente gli attributi necessari nell'interfaccia utente, non di più, e si utilizza AutoMapper per fornire il contenuto di quegli oggetti con un codice di caldaia inferiore.
In una situazione del genere i tuoi "oggetti di visualizzazione" non sono un duplicato della classe originale. Hanno metodi diversi e forse alcuni attributi duplicati. Ma va bene finché usi quegli oggetti di visualizzazione solo per scopi di visualizzazione dell'interfaccia utente e non inizi a usarli in modo improprio per manipolazione dei dati o operazioni aziendali.
Un altro argomento che potresti leggere per capire meglio questo è il modello di segregazione Responsabilità delle query dei comandi di Fowlers , al contrario di CRUD. Mostra le situazioni in cui hanno senso diversi modelli di oggetti per la query dei dati e l'aggiornamento in un database. Qui, la mappatura da un modello a oggetti a un altro può essere eseguita anche da uno strumento come AutoMapper.
La duplicazione delle lezioni è mai utile / di buon design?
È buona norma disporre di una classe del modello di vista separata da utilizzare nel livello dell'interfaccia utente anziché utilizzare la stessa classe utilizzata nel livello dati. Potrebbe essere necessario che la tua UI / pagina web visualizzi altri bit di informazioni non strettamente correlati all'entità dati. Creando questa classe extra, ti stai dando la libertà di modificare facilmente la tua interfaccia utente man mano che i requisiti cambiano nel tempo.
Per quanto riguarda l'utilizzo di AutoMapper, lo evito personalmente per 3 motivi:
Insuccessi silenziosi più comuni
Poiché AutoMapper esegue il mapping automatico tra le proprietà, la modifica di un nome di proprietà su una classe e non sull'altra farà saltare la mappatura delle proprietà. Il compilatore non lo saprà. A Automapper non importa.
Mancanza di analisi statiche
Quindi ti è stata data una grande base di codice da gestire. Ci sono un milione di classi con un milione di proprietà. Sembra che non vengano utilizzati o siano duplicati. Lo strumento "Trova tutti i riferimenti" in Visual Studio ti aiuterà a vedere dove vengono utilizzate le proprietà e ti aiuterà a costruire una mappa nella testa di come l'intera applicazione si blocca. Ma aspetta, non ci sono riferimenti espliciti a metà delle proprietà perché viene utilizzato Automapper. Il mio lavoro ora è molto più difficile.
Requisiti tardivi che aumentano la complessità
Automapper è tutto a posto quando vuoi solo copiare i valori da UNA classe a un'altra (come spesso accade all'inizio dello sviluppo), ma ricordi quei requisiti che cambiano nel tempo? Cosa succede se ora è necessario ottenere valori da altre parti dell'applicazione, forse specifici dell'utente che ha effettuato l'accesso o di qualche altro stato contestuale?
Il modello di AutoMapper per la creazione dei mapping di classe one-to-one all'avvio dell'applicazione non si presta bene a questo tipo di cambiamenti specifici del contesto. Sì, probabilmente ci sono modi per farlo funzionare, ma di solito trovo più pulito, semplice ed espressivo scrivere la logica da solo.
In sintesi, prima di raggiungere Automapper per risparmiare 30 secondi di mappatura manuale di una classe su un'altra, pensaci.
La programmazione è l'arte di dire a un altro essere umano cosa si vuole fare dal computer. - Donald Knuth
Con questo in mente, chiediti "AutoMapper è utile oggi e sarà domani?"
Nella mia esperienza, quando qualcuno si è lamentato di "troppo boilerplate" e desidera utilizzare AutoMapper, è stato uno dei seguenti:
Tuttavia:
Se hai scelto una lingua tipicamente statica, approfitta della lingua. Se stai tentando di eludere i controlli nella lingua che aiutano a prevenire errori dovuti a un uso eccessivo di API di riflessione e magiche come AutoMapper, significa solo che hai scelto un linguaggio che non è soddisfacente per le tue esigenze.
Inoltre, solo perché Microsoft ha aggiunto funzionalità a C # non significa che sono un gioco equo in ogni situazione o che supportano le migliori pratiche. Reflection e la parola chiave "dinamica", per esempio, dovrebbero essere usati nei casi in cui semplicemente non puoi realizzare ciò di cui hai bisogno senza di loro. AutoMapper non è una soluzione per nessun caso d'uso che non può essere risolto senza di essa.
Quindi, la duplicazione delle classi è cattiva progettazione? Non necessariamente.
AutoMapper è una cattiva idea? Si assolutamente.
L'uso di AutoMapper indica carenze sistemiche nel progetto. Se ti senti di averne bisogno, fermati e pensa al tuo design. Troverai sempre un design migliore, più leggibile, più gestibile e più privo di bug.
C'è un problema più profondo qui: il fatto che C # e Java insistano sul fatto che la maggior parte / tutti i tipi devono essere distinguibili per nome piuttosto che per struttura: ad esempio, class MyPoint2D
e class YourPoint2D
sono tipi separati anche se hanno le stesse identiche definizioni. Quando il tipo che desideri è "qualcosa di anonimo con un x
campo e un y
campo" (cioè un record ), sei sfortunato. Quindi, quando vuoi trasformare a YourPoint2D
in a MyPoint2D
, hai tre opzioni:
this.x = that.x; this.y = that.y
La scelta 1 è abbastanza facile a piccole dosi ma diventa rapidamente un lavoro ingrato quando il numero di tipi che è necessario mappare è elevato.
La scelta 2 è meno desiderabile perché ora è necessario aggiungere un ulteriore passaggio al processo di generazione per generare il codice e assicurarsi che l'intero team riceva il memo. Nel peggiore dei casi è necessario creare anche il proprio generatore di codice o sistema di template.
Questo ti lascia con la riflessione. Puoi farlo da solo o puoi usare AutoMapper.
Automapper è una di quelle librerie / strumenti in cui l'imperatore corre letteralmente in giro nudo. Quando superi il logo sfarzoso, ti rendi conto che non fa nulla che non puoi fare manualmente con risultati molto migliori.
Sebbene non sia del tutto sicuro di come accenni ai membri di auto-mapping, molto probabilmente comporta una logica di runtime aggiuntiva e una possibile riflessione. Questa potrebbe essere una penalità di prestazione significativa in cambio di un risparmio di tempo. La mappatura manuale, d'altra parte, il suggerimento viene eseguito molto prima del tempo di compilazione.
Nei casi in cui AutoMapper non ha idea, è necessario configurare la mappatura con codice e flag di impostazione. Se hai intenzione di preoccuparti di fare tutto il lavoro di installazione e codice, devi chiederti quanto risparmia sulla mappatura manuale.