62 messaggi dal 22 ottobre 2012
Salve volevo un consiglio, ho strutturato una mia applicazione secondo il modello indicato nel link sotto riportato:

https://chsakell.com/2015/02/15/asp-net-mvc-solution-architecture-best-practices/

In questa soluzione nella classe UnitOfWork e' presente il solo metodo per eseguire il Commit, viene gestita solo la persistenza dei dati.

In altre documentazione riguardanti UnitofWork tipo:
https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

dalla classe UnitOfWork si accede anche ai repository.

Qual e' la soluzione corretta da seguire ?

Oltre a questo se dalla mia applicazione mi servisse accedere a 2 database devo avere una classe UnitOfWork distinta per ogni DB ( contesto ). ( I DB hanno strutture diverse )
11.886 messaggi dal 09 febbraio 2002
Contributi
Non c'è una "maniera corretta". La validità di ogni soluzione va valutata nel proprio contesto e la sua applicabilità deve tenere in considerazione le preferenze dei singoli sviluppatori. A te quale soluzione piacerebbe adottare tra le due?

A me nessuna delle due, ma è una mia opinione personale. Penso che DbContext e DbSet stiano già implementando i pattern Unit of Work e Repository e che un ulteriore livello di astrazione aggiunga poco valore. Lavorare direttamente con IQueryable è così utile e flessibile che mi sembra un peccato andare a nasconderlo dietro metodi che restituiscono IEnumerable.

Aggiungere una classe che segue il pattern Unit of Work per me ha senso quando hai più di un database o comunque più fonti dati che possono anche essere eterogenee tra loro. In questo caso (non troppo comune) i repository aiutano a nascondere i vari meccanismi di persistenza dietro una API omogenea, che semplifica il lavoro mentre sviluppi lo strato di servizi applicativi.


dalla classe UnitOfWork si accede anche ai repository.

Su questo specifico tema, la scelta può essere influenzata dal principio della interface segregation.
Il principio dice che ogni interfaccia non dovrebbe esporre più membri di quelli che vengono poi effettivamente usati da un dato componente.
Siccome è impossibile che ciascuno dei controller e servizi applicativi necessitino di TUTTI i repository esposti dallo UoW, allora qualcuno preferisce non averli affatto nello UoW. Ogni controller e servizio applicativo manifesterà la sua dipendenza dai repository che gli servono prendendoli come parametri del suo costruttore. Un container IoC gli fornirà le istanze di tali repository.

ciao,
Moreno

Enjoy learning and just keep making
62 messaggi dal 22 ottobre 2012
Grazie per la risposta.

Nella mia applicazione ho la necessità di accedere a 3 DB diversi e volevo farlo utilizzano la stessa applicazione Web.

Due DB sono MS-SQL e uno con IBM Informix ( dove ho le anagrafiche principali, anagrafiche articoli, clienti, fornitori .....)
Nei primi 2 ho la necessità di gestire la persistenza mentre in Informix solo selezioni per lookup e join.

In questa configurazione pensi possa quindi andare bene utilizzare il pattern UoW ?
Se si... devo avere una classe UoW unica dalla quale accedere a tutti i repository ?


Hai qualche link dove posso vedere delle soluzioni senza UoW ma che utilizzano un Service Layer e Data Layer
Modificato da rubinim il 20 febbraio 2017 10.40 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,

dato che hai due database, probabilmente usare il pattern UoW aggiungerà valore se gli lasci almeno gestire le transazioni.
Infatti, che succede se da un componente del tuo software usi un repository che scrive sul DB A e un altro repository che scrive nel DB B e si verifica un errore tra una scrittura e l'altra? Se vuoi che i cambiamenti vengano scritti nei due DB in maniera transazionale, la classe UoW dovrà decidere se e quando è il caso di effettuare i cambiamenti nel contesto di una transazione distribuita.


devo avere

Non "devi" fare nulla. Sei tu a dare forma all'architettura del tuo software, perché conosci meglio di tutti il problema che deve risolvere. Non seguire alla cieca gli articoli che trovi su internet perché chi li ha scritti non poteva conoscere il tuo caso specifico. Cerca di proteggerti dalla cosiddetta "programmazione cargo cult". Quando apprendi un nuovo pattern, analizza criticamente i suoi vantaggi valuta se sono sufficienti a giustificare l'incremento di complessità che introdurrà nella tua applicazione.

ciao,
Moreno

Enjoy learning and just keep making
62 messaggi dal 22 ottobre 2012
Grazie.

Un tuo parete, in una applicazione con un solo DB, niente UoW, soluzione strutturata con Layer UI, Layer Service (BLL), Layer Data (DLL).
Abitualmente per le classiche funzionalità CRUD costruisco una classe service per ogni entity.
Esempio.

T1Controller.class - > T1.Service.class - > .....

Quindi dal controller che mi gestisce le funzionalità CRUD accedo tramite la propria classe di servizio.
Nella classe di servizio tramite IoC accedo al DbContext.

public class T1Service : IT1Service
    {
        private DBEntities dataContext;

        public T1Service(DBEntities dataContext)
        {
            this.dataContext = dataContext;
        }

        public IEnumerable<T1> GetT1s()
        {
            return dataContext.T1s.ToList();                  
        }


Se invece di avere più classi di servizio, questa fosse unica ma con diverse interfacce.
Esempio un'interfaccia che espone i metodi per le funzionalità CRUD di una singola entity e cosi via è a tuo parere una soluzione valida oppure non ha senso.

In alcuni casi mi sono trovato nella necessità di accedere da una classe di servizio a metodi che avevo creato su altre classi di servizio.
Nell'esempio di codice sopra dove all'intero c'è il metodo GetT1s mi servirebbe accedere al metodi GetT2s che è presente su un'altra classe di servizio.

In questo caso quale sarebbe a tuo parere la soluzione più corretta ?
Forse passare nel costruttore della classe di servizio oltre che al DbContext anche le classi di servizio che servono ?
Modificato da rubinim il 21 febbraio 2017 12.19 -

Modificato da rubinim il 23 febbraio 2017 08.06 -

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.