Sfondo: Per la mia formazione di chiarezza/sé, sto cercando di realizzare una semplice applicazione Order Entry usando TDD + DDD. Il mio obiettivo principale è mantenere l'architettura pulita separando le preoccupazioni.Dove implementare Automapper in DDD + architettura a strati
Ho quattro strati (per ora) ...
Persistenza/DAL con una classe CustomerRepository in grado di eseguire GetById, Salva, le operazioni sul "root aggregata", un cliente e le sue Ordini correlati e OrderItems. Per consentire "l'iniezione di dipendenza da uomo povero"
Livello dominio/BLL contenente classi "entità aziendali" che eseguono operazioni a grana fine per aiutare a creare nuovi ordini, applicare tasse, sconti, logica di spedizione in base alla dimensione dell'ordine e posizione del cliente.
Application Facade (servizi di app/orchestrazione) contenente classi complesse e di grana grossa per orchestrare le "entità di business" e ridurre le chatter con la presentazione (e potenzialmente un livello di WebServices).
livello di presentazione
Inoltre, voglio passare POCO DTO tra gli strati chiave ... in particolare tra gli strati di persistenza => dominio e ApplicationFacade => livelli di presentazione. Quindi, ho CustomerDto, OrderDto, OrderItemDto con le relazioni appropriate definite in un pacchetto condiviso.
Voglio iniettare un'implementazione dell'ICustomerRepository nella classe "business entity" del cliente utilizzando Constructor Injection, quindi chiamare Customer.Save() sulla "entità aziendale" per avviare il processo di creazione/aggiornamento, in definitiva chiamando il metodo Save sul CustomerRepository. Dopo tutto, il Cliente è la "radice aggregata" e ha tutte le informazioni necessarie per salvare ... è anche il "custode" del CustomerRepository immesso.
Problema: Qui è dove ho colpito un intoppo. Voglio mantenere il Dominio/BLL Layer il più puro possibile ed evitare di accoppiarlo a qualsiasi framework e API di terze parti, ma il metodo Customer.Save() deve tradurre il Cliente "radice aggregata" e tutti i suoi Ordini e OrderItem nelle loro versioni DTO per il trasporto al layer di Persistenza inserito CustomerRepository ... e questo è un lavoro per Automapper.
Il problema è ... Se non metto Automapper nel livello Dominio/BLL, non sono proprio sicuro che sia dove dovrebbe andare.
Non è corretto inserirlo in ApplicationFacade anche se il lavoro è un'orchestrazione.
Non è assolutamente giusto inserirlo nel livello Dominio/BLL perché voglio mantenerlo intatto.
Pertanto, mi sento come se mi sia sfuggito qualcosa ... che mi sto avvicinando a questo con un fondamentale fraintendimento su come le parti di lavoro dovrebbero riunirsi per completare questo compito. Eventuali suggerimenti? (Si prega di essere gentile, sono nuovo di tutto questo e nuovo di SO. Fammi sapere se ho bisogno di mostrare un codice di quello che ho finora.)
Wow, grazie! Ottima risposta Sono completamente d'accordo con i primi due paragrafi: le distinzioni che hai individuato sono esatte. Gli ultimi due paragrafi mi serviranno più tempo per digerire, leggere alcuni dei riferimenti che hai fatto (in particolare l'architettura esagonale e il servizio host aperto) e vedere come questo impatta sul mio piccolo esperimento. Grazie mille per il tempo impiegato per rispondere. –
Followup riguardante l'ultima frase del terzo paragrafo ... la mia motivazione per il ritorno di DTO dal livello applicationfacade/services - al contrario di restituire istanze di "entità aziendali" POCO al livello di presentazione - era di nascondere la grana più fine metodi definiti su ciascuna delle entità aziendali nel livello dominio/BLL. Voglio che quei metodi a grana fine vengano consumati dal livello applicationfacade/services NOT del livello di presentazione. Quindi, alla luce di ciò, c'è qualcosa che dovrei fare? Ho visto alcune interfacce di definizione per le loro entità di business. –
Non definirei le interfacce per gli oggetti dominio perché DTO e oggetti dominio non sono sempre one-one. Puoi semplicemente creare DTO per passare tra i servizi applicativi e il livello di presentazione e mapparli con AutoMapper all'interno del servizio dell'applicazione. Di nuovo, questi DTO non corrispondono necessariamente direttamente a un oggetto dominio. Possono rappresentare argomenti per un metodo di caso d'uso del servizio applicativo specifico o valori di ritorno. Per un caso d'uso che crea una nuova entità, il DTO può assomigliare molto all'oggetto dominio corrispondente. – eulerfx