2012-03-26 19 views
1

Ich habe meinen Fluent NHibernate-Setup-Code in einem DataAccess-Projekt, auf das über meine Webanwendung zugegriffen wird.DRY-Modelle mit fließendem NHibernate und ASP.NET MVC

Als Teil der NHibernate-Konfiguration habe ich ein Model definiert, das bei der Zuordnung zur Datenbank verwendet werden soll.

public sealed class MyTypeMapping: ClassMap<MyType> 

Dieses Modell MyType ist identisch mit einem Modell, das ich in meiner Web-Schicht benötigen, um eine Ansicht übergeben werden. Ich möchte auch einige zusätzliche Metadaten zu diesem Modell wie Required und DisplayName hinzufügen.

Ich bin mir sicher, dass dies ein übliches Szenario ist, bei dem Modelle in der Datenzugriffsebene den Modellen entsprechen, die in der Webschicht benötigt werden.

Wie wird das normalerweise gehandhabt? Ist es eine gängige Praxis, eine Ansicht von einem Modell in der Datenzugriffsebene abhängig zu machen, oder sollte ich einfach ein ViewModel erstellen, um die Details von der Ansicht wegzuspalten?

Ich bin ziemlich neu in ORM und es fühlt sich komisch an, meine Modelle außerhalb meines Models-Ordners im MVC-Projekt zu haben und das Modell zu duplizieren fühlt sich auch nicht richtig an.

Wie gehen Sie damit um?

Antwort

2

Ist es eine akzeptierte Praxis eine Ansicht, abhängig von einem Modell in der Datenzugriffsschicht

vielleicht für einige Leute zu machen, für mich nicht.

oder sollte ich einfach ein ViewModel erstellen, um die Details von der Ansicht zu abstrahieren?

Das würde ich tun.

Natürlich, wenn Sie nicht meinem Vorschlag der Verwendung von Ansichtsmodellen folgen möchten, haben Sie ein paar Möglichkeiten. Nehmen wir an, dass Sie das folgende Domänenmodell haben:

, aber Sie wollten einige Metadaten damit verknüpfen.

Die erste Möglichkeit, die Sie haben und welches eingebaute in ist das [MetadataType] Attribut zu verwenden:

[MetadataType(typeof(MyDomainModelMetadata))] 
public class MyDomainModel 
{ 
    public string Foo { get; set; } 
} 

und haben eine eigene Klasse für die Metadaten:

public class MyDomainModelMetadata 
{ 
    [Display(Name = "foo bar")] 
    public object Foo { get; set; } 
} 

Aber noch Ihre DAL muss über Metadaten und Präsentationslogik Bescheid wissen, was nicht ganz gut ist. Die Klasse MyDomainModelMetadata muss in Ihrer DAL definiert sein, da Attribute Metadaten darstellen, die zur Kompilierungszeit in die Assembly eingebunden werden.

Was uns auf die zweite Möglichkeit bringt, bestehend aus einem benutzerdefinierten Modell Metadaten-Anbieter schreiben:

public class MyMetadataProvider : DataAnnotationsModelMetadataProvider 
{ 
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) 
    { 
     // TODO: you could keep a static hashtable that will map between your 
     // domain model type and the associated metadata type in your UI layer 
     // but for the purpose of this demonstration I have hardcoded them to simplify 
     if (containerType == typeof(MyDomainModel)) 
     { 
      return GetMetadataForProperty(
       modelAccessor, 
       typeof(MyDomainModelMetadata), 
       propertyName 
      ); 
     } 
     return base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); 
    } 
} 

, die in ihrem Application_Start und welche zugelassen werden, den Standard-Metadaten-Anbieter ersetzen:

ModelMetadataProviders.Current = new MyMetadataProvider(); 

Jetzt können Sie das MetadataType Attribut in Ihrem Domänenmodell loswerden und die MyDomainModelMetadata Klasse in Ihrer UI-Schicht (die MVC-Anwendung selbst) haben.

+0

Danke für die Klarstellung Darin. –

+0

Vielen Dank für die Erweiterung Ihrer Antwort. Sehr interessant und sehr geschätzt. –