Der spaßige Teil: diese ist nicht auf viewmodels
in MVC
, es ist eigentlich eine Frage der Trennung von den „guten alten Daten/Unternehmen/ui Schichten“ heißt Trennung von Bedenken. Ich werde das später illustrieren, aber für jetzt; Denken Sie daran, es gilt auch für MVVM
oder ein anderes Design-Muster.
Ist es akzeptabel, dass ein ViewModel Instanzen von Domänenmodellen enthält?
Grundsätzlich nicht, obwohl ich sehe es oft passieren. Es hängt ein bisschen von der quick-win
Ebene Ihres Projekts ab.
Lassen Sie mich ein Beispiel geben. Stellen Sie sich folgende Ansicht Modell:
public class FooViewModel
{
public string Name {get; set;}
public DomainClass Genre {get;set;}
}
und die folgende DomainClass
//also applies to database data/POCO classes
public class DomainClass
{
public int Id {get; set;}
public string Name {get;set;}
}
Also, irgendwo in Ihrem Controller füllen Sie das FooViewModel und übergeben es an Ihrer Ansicht auf. Jetzt
, sollten Sie die folgenden Szenarien:
1) Das Domänenmodell ändert.
In diesem Fall müssen Sie wahrscheinlich auch die Ansicht anpassen, dies ist eine schlechte Praxis im Zusammenhang mit der Trennung von Bedenken.
Wenn Sie das ViewModel vom DomainModel getrennt haben, wäre eine geringfügige Anpassung der Zuordnungen (ViewModel => DomainModel (und zurück)) ausreichend.
2) Die DomainClass hat verschachtelte Eigenschaften und Ihre Ansicht zeigt nur GenreName
an.
Ich habe gesehen, dass dies in echten Live-Szenarien falsch läuft.
In diesem Fall ist ein häufiges Problem, dass die Verwendung von @Html.EdittorFor
zu Eingaben für das verschachtelte Objekt führt. Dies könnte Id
s und andere vertrauliche Informationen enthalten. Nach diesem Kurs erstellen Sie hidden
Eingaben. Wenn Sie dies mit einem serverbasierten Modelbinding oder Auto-Mapper kombinieren, ist es sehr schwierig die Manipulation von versteckten Id
's mit Tools wie Firebug zu blockieren.
Obwohl es möglich, vielleicht einfach ist, einige dieser Felder zu blockieren, je mehr geschachtelte Domänen-/Datenobjekte Sie haben, desto schwieriger wird es, diesen Teil zu sichern.Denken Sie daran, dass Sie möglicherweise Ihr DomainModel aus einem Grund ändern möchten, der nicht unbedingt auf die Ansicht ausgerichtet ist. Mit jeder Änderung in Ihrem DomainModel sollten Sie sich bewusst sein, dass die Ansicht und die Sicherheitsaspekte des Controllers beeinflussen können.
3) In asp.net-MVC ist es üblich, Validierungsattribute zu verwenden.
Möchten Sie wirklich, dass Ihre Domain Metadaten zu Ihren Ansichten enthält? Oder wenden Sie View-Logik auf Ihre Datenebene an? Ist Ihre View-Validierung immer die gleiche wie die Domain-Validierung? Hat es die gleiche Validierungslogik? Verwenden Sie Ihre domänenübergreifende Anwendung? usw.
Ich denke, es ist klar, das ist nicht der Weg zu nehmen.
4) Mehr
kann ich Sie mehr Szenarien, aber es ist nur eine Frage des Geschmacks, was attraktiver ist. Ich werde nur an dieser Stelle hoffen, werden Sie erhalten den Punkt :) Trotzdem versprach ich eine Illustration:
Nun, für wirklich schmutzig und quick-wins
es funktionieren wird, aber ich glaube nicht, dass Sie sollte es wollen.
Es ist nur ein wenig mehr Aufwand, ein View-Modell zu erstellen, das normalerweise für 80 +% ähnlich dem Domain-Modell ist. Dies könnte das Gefühl, dass unnötige Zuordnungen zu tun, aber wenn der erste konzeptionelle Unterschied entsteht, werden Sie feststellen, dass es sich lohnt die Mühe hat :)
So als Alternative, schlage ich vor, die folgende Einstellung für einen allgemeinen Fall:
- ein Ansichtsmodell
- erstellen domainmodel
- erstellen Datenmodell
- verwenden, um eine Bibliothek wie
automapper
erstellen Mapping von einem zum anderen erstellen (dies Foo.FooProp
-zur Karte helfen)
Die Vorteile sind z. Wenn Sie ein zusätzliches Feld in einer Ihrer Datenbanktabellen erstellen, wirkt sich dies nicht auf Ihre Ansicht aus. Es könnte Ihre Business-Ebene oder Zuordnungen treffen, aber dort wird es aufhören. Natürlich, die meiste Zeit möchten Sie auch Ihre Ansicht ändern, aber in diesem Fall brauchen Sie nicht zu. Es hält daher das Problem in einem Teil Ihres Codes isoliert.
web api/Daten-Schicht
Noch ein weiteres konkretes Beispiel dafür, wie diese in einem Web-API/EF Szenario funktioniert:
note
Wie @mrjoltcola sagte: Es gibt auch eine zu starke Komponente, die man im Hinterkopf behalten sollte. Wenn keiner der oben genannten Punkte zutrifft und den Benutzern/Programmierern vertraut werden kann, ist es gut zu gehen. Bedenken Sie jedoch, dass Wartbarkeit und Wiederverwendbarkeit aufgrund der Mischung von DomainModel/ViewModel verringert werden.
Es könnte gefährlich sein, vollen Zugriff auf das Modellobjekt zu geben, wie bei Ihrem ersten Ansatz. Die bessere Option wäre, wenn Sie Ihr Modell im privaten Bereich haben und nur Eigenschaften anzeigen, die für die Ansicht benötigt werden. z.B. Öffentliche Zeichenfolge Titel {get {return this.album.Title; } set {this.album.Title = Wert;}} –