MVC + 3 livelli; dove entrano in gioco ViewModels?


11

Sto progettando un'applicazione a 3 livelli usando ASP.NET MVC 4. Ho usato le seguenti risorse come riferimento.

Finora ho il seguente desingn.

Presentation Layer (PL) (progetto MVC principale, in cui M di MVC è stato spostato nel livello di accesso ai dati):

MyProjectName.Main
    Views/
    Controllers/
    ...

Livello logico aziendale (BLL) :

MyProjectName.BLL
    ViewModels/
    ProjectServices/
    ...

Data Access Layer (DAL) :

MyProjectName.DAL
    Models/
    Repositories.EF/
    Repositories.Dapper/
    ...

Ora, riferimenti PL BLL e riferimenti BLL DAL. In questo modo il livello inferiore non dipende da quello sopra di esso.

In questo progetto, PL invoca un servizio di BLL. PL può passare un View Model a BLL e BLL può passare un View Model a PL.

Inoltre, BLL invoca il livello DAL e il livello DAL può restituire un modello a BLL. BLL può a sua volta creare un modello di visualizzazione e restituirlo a PL.

Fino ad ora questo schema funzionava per me. Tuttavia, ho riscontrato un problema in cui alcuni dei miei ViewModels richiedono join su più entità. Nel semplice approccio MVC, nel controller ho usato una query LINQ per fare se joinpoi select new MyViewModel(){ ... }. Ma ora, nel DAL non ho accesso a dove sono definiti ViewModels (nel BLL).

Questo significa che non posso fare join in DAL e restituirlo a BLL. Sembra che devo fare query separate in DAL (invece di unirmi in una query) e BLL userebbe quindi il risultato di queste per costruire un ViewModel. Questo è molto scomodo, ma non credo che dovrei esporre DAL a ViewModels.

Qualche idea su come posso risolvere questo dilemma? Grazie.

Risposte:


18

progetto MVC principale, in cui M di MVC è stato spostato nel livello di accesso ai dati

Malinteso comune. Il Mof MVCnon ha nulla a che fare con i dati, nonostante i molti esempi e tutorial che lo affermano.

M è il tuo ViewModel e dovrebbe risiedere nel tuo progetto MVC. I ViewModel che hai nel tuo BLL in realtà devono essere denominati DataContracts o BusinessModels.

Nel tuo controller hai qualcosa di paragonabile a questo:

Get(id):
    dataContract = _service.Get(id);
    viewModel = Map(dataContract);
    return viewModel

Al tuo servizio, qualcosa del genere:

Get(id):
    dataModel = _dataAccess.Get(id);
    dataContract = Map(dataModel);
    return dataContract;

E in DataAccess, si eseguono i join corretti in base all'oggetto richiesto. Ovviamente, sei libero di aggiungere metodi personalizzati a DataAccess quando richiesto, quindi il tuo servizio può chiamare questi metodi:

GetWithBars():
    dataModels = _repository.Query("select from foos join bars");
    return dataModels;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.