MVC + 3 Tier; Wo kommen ViewModels ins Spiel?

11

Ich entwerfe eine dreistufige Anwendung mit ASP.NET MVC 4. Ich habe die folgenden Ressourcen als Referenz verwendet.

Ich habe das folgende Design bisher.

Präsentationsschicht (PL) (Haupt-MVC-Projekt, bei dem M von MVC in die Datenzugriffsschicht verschoben wurde):

MyProjectName.Main
    Views/
    Controllers/
    ...

Business Logic Layer (BLL) :

MyProjectName.BLL
    ViewModels/
    ProjectServices/
    ...

Datenzugriffsschicht (DAL) :

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

Jetzt verweist PL auf BLL und BLL auf DAL. Auf diese Weise hängt die untere Schicht nicht von der darüber liegenden ab.

In diesem Entwurf ruft PL einen Dienst der BLL auf. PL kann ein Ansichtsmodell an BLL übergeben und BLL kann ein Ansichtsmodell an PL zurückgeben.

Außerdem ruft BLL die DAL-Ebene auf und die DAL-Ebene kann ein Modell an BLL zurückgeben. BLL kann wiederum ein Ansichtsmodell erstellen und an PL zurückgeben.

Bisher hat dieses Muster für mich funktioniert. Ich bin jedoch auf ein Problem gestoßen, bei dem einige meiner ViewModels Verknüpfungen für mehrere Entitäten erfordern. Beim einfachen MVC-Ansatz habe ich im Controller eine LINQ-Abfrage verwendet, um joins und dann auszuführen select new MyViewModel(){ ... }. Aber jetzt habe ich im DAL keinen Zugriff darauf, wo ViewModels definiert sind (in der BLL).

Dies bedeutet, dass ich keine Joins in DAL durchführen und an BLL zurückgeben kann. Es scheint, dass ich separate Abfragen in DAL durchführen muss (anstatt Verknüpfungen in einer Abfrage), und BLL würde dann das Ergebnis dieser Abfragen verwenden, um ein ViewModel zu erstellen. Dies ist sehr unpraktisch, aber ich denke nicht, dass ich DAL ViewModels aussetzen sollte.

Irgendwelche Ideen, wie ich dieses Dilemma lösen kann? Vielen Dank.

Nomade
quelle

Antworten:

18

Haupt-MVC-Projekt, bei dem M von MVC in die Datenzugriffsschicht verschoben wurde

Häufiges Missverständnis. Das Mvon MVChat nichts mit Daten zu tun, trotz der vielen Beispiele und Tutorials, die dies behaupten.

M ist Ihr ViewModel und sollte sich in Ihrem MVC-Projekt befinden. Die ViewModels, die Sie in Ihrer BLL haben, heißen eigentlich DataContracts oder BusinessModels.

In Ihrem Controller haben Sie etwas Vergleichbares:

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

In Ihrem Dienst so etwas:

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

Und im DataAccess führen Sie die richtigen Verknüpfungen entsprechend dem angeforderten Objekt durch. Es steht Ihnen jedoch natürlich frei, Ihrem DataAccess bei Bedarf benutzerdefinierte Methoden hinzuzufügen, damit Ihr Dienst diese Methoden aufrufen kann:

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