MVC + 3 niveaux; où les ViewModels entrent en jeu?

11

Je conçois une application à trois niveaux à l'aide d'ASP.NET MVC 4. J'ai utilisé les ressources suivantes comme référence.

J'ai le design suivant jusqu'à présent.

Presentation Layer (PL) (projet MVC principal, où M de MVC a été déplacé vers Data Access Layer):

MyProjectName.Main
    Views/
    Controllers/
    ...

Couche logique métier (BLL) :

MyProjectName.BLL
    ViewModels/
    ProjectServices/
    ...

Couche d'accès aux données (DAL) :

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

Maintenant, PL fait référence à BLL et BLL fait référence à DAL. De cette façon, la couche inférieure ne dépend pas de celle au-dessus.

Dans cette conception, PL invoque un service du BLL. PL peut transmettre un modèle de vue à BLL et BLL peut renvoyer un modèle de vue à PL.

De plus, BLL invoque la couche DAL et la couche DAL peut renvoyer un modèle à BLL. BLL peut à son tour créer un modèle de vue et le renvoyer à PL.

Jusqu'à présent, ce modèle fonctionnait pour moi. Cependant, j'ai rencontré un problème où certains de mes ViewModels nécessitent des jointures sur plusieurs entités. Dans l'approche MVC simple, dans le contrôleur, j'ai utilisé une requête LINQ pour faire joins puis select new MyViewModel(){ ... }. Mais maintenant, dans le DAL, je n'ai pas accès à l'endroit où les ViewModels sont définis (dans le BLL).

Cela signifie que je ne peux pas faire de jointures dans DAL et le renvoyer à BLL. Il semble que je doive faire des requêtes distinctes dans DAL (au lieu de jointures dans une seule requête) et BLL utiliserait alors le résultat de celles-ci pour construire un ViewModel. C'est très gênant, mais je ne pense pas que je devrais exposer DAL à ViewModels.

Des idées sur la façon de résoudre ce dilemme? Merci.

nomade
la source

Réponses:

18

projet MVC principal, où M de MVC a été déplacé vers Data Access Layer

Idée fausse commune. Le Mof MVCn'a rien à voir avec les données, malgré les nombreux exemples et tutoriels qui le prétendent.

M est votre ViewModel et doit résider dans votre projet MVC. Les ViewModels que vous avez dans votre BLL doivent en fait être appelés DataContracts ou BusinessModels.

Dans votre contrôleur, vous avez quelque chose de comparable à ceci:

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

À votre service, quelque chose comme ça:

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

Et dans DataAccess, vous effectuez les jointures appropriées en fonction de l'objet demandé. Vous êtes cependant bien sûr libre d'ajouter des méthodes personnalisées à votre DataAccess si nécessaire, afin que votre service puisse appeler ces méthodes:

GetWithBars():
    dataModels = _repository.Query("select from foos join bars");
    return dataModels;
CodeCaster
la source