Come organizzare DAL in ASP.NET MVC

Sto cercando di organizzare il livello di accesso ai dati nel progetto asp.net mvc. Ho letto molti articoli diversi su questo, quindi ho ancora alcune domande per finire con questo problema:

  1. Devo creare istanze di repository per ogni quadro nel database o per tutte o una istanza PostRepository , ad esempio PostRepository può includere entity framework come Post , Comment e Tag ?

  2. Nel controller devo ottenere alcuni dati, trasformarli in ViewModel e passarli in vista. Dov’è il posto migliore per farlo? Services , Controller o qualcos’altro?

  3. Se è Service . Quanti servizi dovrei creare? Anche per ogni quadro e passare in Controller 3 o 4 servizi se è necessario? O forse farlo come volevo farlo nel repository? (Creare un servizio comune che contenga alcuni conteggi di repository PostService , con repository come PostRepository , TagRepository e TagRepository )

Ecco la mia opinione:

Devo creare istanze di repository per ogni quadro nel database o per tutte o una istanza genereal, ad esempio PostRepository può includere quadro come Post, Comment e Tag?

Avere un unico repository generico ti farà risparmiare un sacco di problemi di manutenzione. Potresti implementare un singolo repository generico come:

 ///  /// This interface provides an abstraction for accessing a data source. ///  public interface IDataContext : IDisposable { IQueryable Query() where T : class; T Add(T item) where T : class; int Update(T item) where T : class; void Delete(T item) where T : class; ///  /// Allow repositories to control when SaveChanges() is called ///  int SaveChanges(); } 

e implementare l’interfaccia di cui sopra in una singola class di contesto.

Alcune persone implementano anche repository specifici separati.

Nel controller devo ottenere alcuni dati, trasformarli in ViewModel e passarli in vista. Dov’è il posto migliore per farlo? Servizi, controller o qualcos’altro?

Definire tutte le classi del modello (DTO o quadro o POCO) in un assieme separato accessibile da DA, servizio e Web. I metodi di servizio restituiscono l’istanza del modello, il controller li converte in viewmodel (usa AutoMapper) e passa alla visualizzazione. Di nuovo nel controller del metodo post convertire prima la VM in Model e quindi passare al livello di servizio per la persistenza o l’elaborazione.

Se è servizio. Quanti servizi dovrei creare? Anche per ogni quadro e passare in Controller 3 o 4 servizi se è necessario? O forse farlo come volevo farlo nel repository? (Creare un servizio comune che contenga alcuni conteggi di repository PostService, con repository come PostRepository, CommentRepository e TagRepository)

Vi consiglio caldamente di definire un servizio molto specifico. Utilizzare il principio della singola responsabilità per definire i propri servizi. Ogni servizio dovrebbe fornire un set di funzioni correlate. Ad esempio, AuthService autenticherà l’utente non inviando loro email, quel lavoro di EmailService.

Lo schema che suggerisco funziona molto bene con diversi servizi. Per esempio:

 public class DriverSearchService : IDriverSearchService { private readonly IBlobService _blobService; private readonly IDataContext _dataContext; public DriverSearchService(IDataContext dataContext, IBlobService blobService) { _blobService = blobService; _dataContext = dataContext; } public void SaveDriveSearch(int searchId) { // Fetch values from temp store and clear temp store var item = context.Query().Single(s => s.SearchId == searchId); // Temp object is latest so update the main store var mainSearch = context.Query().Single(s => s.Id == searchId); mainSearch.LastExecutedOn = DateTime.UtcNow; mainSearch.DataAsBlob = item.DataAsBlob; context.Update(mainSearch); } } 

Fondamentalmente sono d’accordo con ciò che @ChrFin ha commentato sul tuo post, ma voglio comunque rispondere alle tue domande.

  1. Sì, ma solo se necessario. Dovresti considerare che l’ quadro Post può avere proprietà virtuali che fanno riferimento ad altre entity framework. In tal caso, potrebbe non essere necessario un repository separato. Tuttavia, è necessario considerare i problemi di prestazioni durante il caricamento delle quadro correlate.

  2. Dalla mia esperienza, il posto migliore per mappare il ViewModel è il livello di servizio o il livello manager: dipende da come lo si vuole chiamare. Cerco sempre di mantenere il mio controller il più sottile ansible. Man mano che le applicazioni crescono, potresti voler riutilizzare la tua logica in altre applicazioni, ad es. WCF. Se hai trasformazioni, logica aziendale, altre cose nei tuoi controllori non sarai in grado di condividerle .

  3. Dipende. Se si desidera evitare dipendenze multiple nel controller (che hanno anche impatto sui test delle unità), è necessario creare un solo servizio per controller, poiché ho affermato che non è la regola. Il servizio potrebbe contenere più repository. Generalmente, non si vogliono tanti servizi quanti repository.

Se stai iniziando a sviluppare un’applicazione, dovresti controllare questi collegamenti utili prima di decidere di utilizzare il modello di repository:

Favorisci oggetti di query sui repository

Dì No al pattern del repository nel tuo DAL