Come evitare la duplicazione del codice relativo alle entità condivise nel modello di repository?

2

Sto costruendo un repository per uno schema CRM di grandi dimensioni con un elevato numero di relazioni tra entità.

Alcune entità sono referenziate da quasi tutte le entità, ad es. Persona e Azienda.

Dove ho una radice aggregata come Order, che indirizza l'intestazione dell'ordine, le righe d'ordine ecc. Nel caso in cui l'ordine provenga da un nuovo cliente, devo inserire contemporaneamente un registro di società e di persona .. Fin qui tutto bene.

La difficoltà è che questa è la situazione con molte altre radici aggregate.

Non voglio avere un metodo privato insertPerson(IPerson) in ogni singola implementazione del repository.

Ho un repository clienti che ha già il metodo pubblico InsertCustomer(ICustomer) , che persiste in un'azienda e in un record personale. Ma la mia lettura indica che i repository non dovrebbero dipendere l'uno dall'altro.

Se questo è il caso in cui è giusto che gli archivi dipendano l'uno dall'altro, qual è il modo migliore per farlo? Devo iniettare il Repository clienti nel costone di repository dell'Ordine, passarlo come parametro ai metodi che ne hanno bisogno, o non commettere mai questo male e duplicare il codice identico in tutti i repository, nel caso in cui questi repository necessitino di specializzarlo per il loro specifico contesti?

    
posta RobD 16.01.2014 - 15:46
fonte

3 risposte

2

Sembra un'area in cui il Service Layer potrebbe rivelarsi utile. È possibile iniettare i repository nel livello di servizio e in questo modo ciascun repository non dipende dagli altri e il servizio può coordinare tutti gli inserimenti per una determinata operazione su aggregati.

I dettagli della tua implementazione potrebbero anche guidarti a seconda della misura in cui ti stai affidando a un ORM e devi tenere conto dell'atomicità delle operazioni del repository. Senza saperne di più su questo consiglio può essere meno che utile.

    
risposta data 15.06.2014 - 22:16
fonte
1

Quindi il processo di inserimento di un Ordine per un nuovo Cliente richiede la memorizzazione della nuova Persona corrispondente. Sembra una logica di dominio.

Il processo di cui l'inserimento dell'ordine è una parte è probabilmente in qualche servizio di dominio. Mi aspetto che parte di questo servizio assomigli a questo:

Begin transaction
Call to PersonRepo interface
Call to OrderRepo interface
Complete transaction

Mi rendo conto che le transazioni sono spesso considerate come dettagli di implementazione del database. Tuttavia, e in particolare sotto forma di TransactionScope attorno a un blocco di codice, hanno perfettamente senso come parte della logica del dominio, raggruppando un gruppo di operazioni che sono considerate una modifica intera e inseparabile.

Se pensi di tenerlo fuori dalla logica del dominio e / o consideri questo un dettaglio di implementazione della memorizzazione dell'Ordine, potresti sempre richiedere la Persona come parametro a InsertOrder() , e fare in modo che il repository dell'ordine dipenda sul repository Person. Non ho mai sentito parlare di una cattiva pratica, e un dettaglio dell'infrastruttura che dipende da un altro (nella stessa infrastruttura, non meno!) Mi sembra perfettamente sensato. Indipendentemente da ciò, non consiglierei questa opzione, perché, guardando la logica del dominio risultante, ci si chiede perché sembra che tutto venga archiviato (chiamate alle interfacce del repository) tranne che per la Persona !

    
risposta data 11.08.2017 - 11:38
fonte
0

Composizione e il modello di facciata. Vorrei dividere il tuo repository in due parti: l'interfaccia pubblica e l'effettiva implementazione. In questo modo è possibile implementarlo, ma ha senso per il DB e presentare comunque una buona API al consumatore del repository. Composizione ti consente di riutilizzare l'implementazione del repository clienti negli altri repository che necessitano dell'accesso ai dati dei clienti. Per specializzazione avrei il repository del cliente implementare più interfacce per rendere l'accesso al caso speciale esplicito e minimo, o se le modifiche sono più approfondite, riprendere la composizione (o ereditarietà in base a ciò che ti serve) per riutilizzare l'implementazione di base e fornire l'extra funzionalità.

    
risposta data 16.01.2014 - 16:12
fonte