Qual è il modo migliore: crea il proprio wrapper per DbContext o usa DbContext in Controller

asp.net-core asp.net-core-mvc c# entity-framework-core

Domanda

Nel mio progetto, utilizzo entity framework 7 e asp.net mvc 6 \ asp.net 5 . Voglio creare CRUD per i propri modelli

Come posso fare meglio:

  1. Utilizzare dbcontext dal controller. Nel seguente link l' autore spiega che questo modo è migliore, ma se è giusto per i controller?
  2. Crea il tuo wrapper. Alcune buone pratiche scrivono su cosa è meglio fare il proprio repository.

Non cambierò l'ef con qualcos'altro, quindi non importa, anche se c'è una forte connettività per accedere ai dati da una particolare implementazione e so che in ef7 dbcontext ha immediatamente implementato gli schemi di Unità di lavoro e Repository.

Risposta accettata

La risposta alla tua domanda è principalmente basata sull'opinione pubblica. Nessuno può dire in modo definitivo "un modo è meglio dell'altro" finché non viene data risposta a molte altre domande. Qual è la dimensione / ambito / budget del tuo progetto? Quanti sviluppatori ci lavoreranno? Avrà solo controller MVC (view-based) o controller API (basati su dati)? In quest'ultimo caso, quanta sovrapposizione ci sarà tra i metodi di azione MVC e API, se presenti? Avrà dei client non web, come WPF? Come pensi di testare l'applicazione?

Entity Framework è uno strumento DAL (Data Access Layer). I controller sono strumenti per la richiesta e la gestione della risposta del client HTTP. A meno che la tua applicazione non sia CRUD pura (che è dubbia), probabilmente ci sarà un qualche tipo di elaborazione di business logic che dovrai fare tra quando ricevi una richiesta web su HTTP e quando salvi i dati di quella richiesta in un database usando EF ( è richiesto il campo X, se si forniscono dati per il campo Y è necessario fornire anche i dati per il campo Z, ecc.). Pertanto, se si utilizza il codice EF direttamente nei controller, significa che la logica di elaborazione aziendale sarà quasi sicuramente presente nei controller insieme ad essa.

Quelli di noi che hanno una discreta esperienza nello sviluppo di applicazioni non banali con .NET tendono a sviluppare opinioni che non dovrebbero essere presenti né in business né in logica di accesso ai dati nei controller a causa di alcune difficoltà che emergono quando viene implementato tale progetto. Ad esempio, quando si inserisce la logica di richiesta e risposta web / http, insieme alla logica aziendale e alla logica di accesso ai dati in un controller, si finisce per dover testare tutti questi aspetti dell'applicazione dalle azioni del controller stesso (che è una violenta violazione del Single Principio di responsabilità, se ti interessa il design SOLID). Supponiamo inoltre che sviluppi un'applicazione MVC tradizionale con controller che restituiscono visualizzazioni, quindi decidi di estendere l'app ad altri client come iOS / Android / WPF / o qualche altro client che non comprende le tue visualizzazioni MVC. Se si decide di implementare un set secondario di azioni del controller basate su dati WebAPI, si duplicherà la logica di accesso business e dati in almeno 2 posizioni.

Tuttavia, questo non prende la decisione di mantenere tutta la business e la logica di accesso ai dati nei controller intrinsecamente "peggio" di un progetto alternativo. Qualsiasi decisione presa nel progettare l'architettura di un'applicazione web avrà vantaggi e svantaggi. Ci saranno sempre dei compromessi indipendentemente dal percorso scelto. I vantaggi di mantenere tutto il codice dell'applicazione nei controller possono includere costi inferiori, complessità e, quindi, time to market. Non ha senso sovraintendere le architetture complesse per applicazioni molto semplici. Per quanto sfortunata, personalmente non ho mai avuto il piacere di sviluppare una semplice applicazione, quindi sono nella barca dell'opinione pubblica che tenere il codice di accesso al business e ai dati nei controller non è "probabilmente" una buona decisione progettuale a lungo termine.

Se sei veramente interessato alle alternative, ti consiglio di leggere questi due articoli . Sono un buon primer su come si potrebbe implementare un modello di comando e query (CQRS) che i controllori possono consumare. EF implementa sia il repository che l'unità di modelli di lavoro out of the box, ma ciò non significa necessariamente che è necessario "avvolgerlo" per spostare il codice di accesso ai dati al di fuori dei controller. Buona fortuna per prendere questo tipo di decisioni per il tuo progetto.

public async Task<ActionResult> Index() {
    var user = await query.Execute(new UserById(1));
    return View(user);
}

Risposta popolare

Di solito preferisco usare il pattern Repository insieme al pattern UnitOfWork ( http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository -e-unit-of-work-patterns-in-un-asp-net-mvc-application ) - Istanzio DbContext in un oggetto istanza UnitOfWork e inserisco DbContext nei repository. Dopo di ciò istanzio UnitOfWork nel controller e il controller non sa nulla di DbContext:

public ActionResult Index()
{
    var user = unitOfWork.UsersRepository.GetById(1); // unitOfWork is dependency injected using Unity or Ninject or some other framework
    return View(user);
}


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché