Voglio porre alcune domande sulle migliori pratiche riguardanti i tipi di mapping e l'utilizzo dei metodi di estensione in C #. So che questo argomento è stato discusso più volte negli ultimi anni, ma ho letto molti post e ho ancora dei dubbi.
Il problema che ho riscontrato è stato l'estensione della classe che possiedo con la funzionalità "convert". Diciamo che ho una "Persona" di classe che rappresenta un oggetto che sarà usato da qualche logica. Ho anche una classe "Cliente" che rappresenta una risposta da API esterna (in realtà ci saranno più di una API, quindi ho bisogno di mappare la risposta di ogni API al tipo comune: Person). Ho accesso al codice sorgente di entrambe le classi e in teoria posso implementare i miei metodi lì. Devo convertire il cliente in persona in modo che possa salvarlo nel database. Il progetto non utilizza alcun programma di mappatura automatico.
Ho in mente 4 possibili soluzioni:
-
.ToPerson () metodo nella classe Consumer. È semplice, ma mi sembra di rompere il pattern di Single Responsibility, specialmente se la classe Consumer è mappata ad altre classi (alcune richieste da un'altra API esterna), quindi dovrebbe contenere più metodi di mapping.
-
Costruttore di mapping nella classe Person che accetta Consumer come argomento. Anche facile e sembra anche spezzare il modello di Responsabilità Unica. Avrei bisogno di avere più costruttori di mappatura (dato che ci sarà classe da un'altra API, fornendo gli stessi dati di Consumer ma in un formato leggermente diverso)
-
Classe di convertitori con metodi di estensione. In questo modo posso scrivere il metodo .PoPerson () per la classe Consumer e quando viene introdotta un'altra API con la sua classe NewConsumer, posso semplicemente scrivere un altro metodo di estensione e mantenerlo tutto nello stesso file. Ho sentito un'opinione secondo cui i metodi di estensione sono in generale cattivi e dovrebbero essere usati solo se assolutamente necessari, quindi è questo che mi trattiene. Altrimenti mi piace questa soluzione
-
Classe Convertitore / Mappatore. Creo una classe separata che gestirà le conversioni e implementerà metodi che considereranno l'istanza della classe di origine come argomento e restituiranno l'istanza della classe di destinazione.
Per riassumere, il mio problema può essere ridotto al numero di domande (il tutto nel contesto di ciò che ho descritto sopra):
-
L'inserimento di un metodo di conversione all'interno dell'oggetto (POCO?) (come il metodo .ToPerson () nella classe Consumer) considera la rottura del modello di responsabilità singola?
-
Sta usando i costruttori di convertitori in una classe (DTO-like) considerata la rottura del modello di responsabilità singola? Soprattutto se tale classe può essere convertita da più tipi di sorgenti, quindi sarebbero necessari più costruttori di conversione?
-
Sta usando i metodi di estensione pur avendo accesso al codice sorgente di classe originale considerato una cattiva pratica? Questo comportamento può essere usato come modello valido per separare la logica o è un anti-pattern?