2009-05-09 10 views
1

Ich erstelle eine Webanwendung, die ASP.NET MVC verwendet, und ich versuche, domänengesteuertes Design zu verwenden. Ich habe eine Architekturfrage.ASP.NET MVC/DDD-Architekturhilfe

Ich habe eine WebControl-Tabelle, um Schlüssel und Werte für Listen zu speichern, damit sie bearbeitet werden können. Ich habe dies in mein Geschäftsmodell integriert, aber es führt zu viel redundantem Code, und ich bin mir nicht sicher, ob es dazu gehört. Zum Beispiel habe ich in meiner Request-Klasse eine Eigenschaft namens NeedType. Da dies aus einer Liste stammt, habe ich eine NeedType-Klasse erstellt, um die Werte für die Optionsfelder bereitzustellen. Ich zeige hier nur ein Beispiel, aber das Formular wird wahrscheinlich ein Dutzend Listen haben, die aus der Datenbank kommen müssen.

[bearbeiten, um Frage zu klären] Was ist eine bessere Möglichkeit, dies zu tun? Sind diese Listenobjekte wirklich Teil meiner Domäne oder existieren sie nur für die Benutzeroberfläche? Wenn sie nicht Teil der Domain sind, dann gehören sie nicht in mein Core-Projekt, also wohin gehen sie?

public class Request : DomainObject 
{ 
    public virtual int RequestId { get; set; } 
    public virtual DateTime SubmissionDate { get; set; } 
    public virtual string NeedType { get; set; } 
    public virtual string NeedDescription { get; set; } 
    // etc. 
} 

public class NeedType : DomainObject 
{ 
    public virtual int NeedTypeId { get; set; } 
    public virtual string NeedTypeCode { get; set; } 
    public virtual string NeedTypeName { get; set; } 
    public virtual int DisplayOrder { get; set; } 
    public virtual bool Active { get; set; } 
} 

public class RequestController : Controller 
{ 
    private readonly IRequestRepository repository; 

    public RequestController() 
    { 
     repository = new RequestRepository(new HybridSessionBuilder()); 
    } 

    public RequestController(IRequestRepository repository) 
    { 
     this.repository = repository; 
    } 

    public ViewResult Index(RequestForm form) 
    { 
     ViewData.Add("NeedTypes", GetNeedTypes()); 
     if (form == null) 
     { 
      form = new RequestForm(); 
      form.BindTo(repository.GetById(125)); 
     } 
    } 

    private NeedType[] GetNeedTypes() 
    { 
     INeedTypeRepository repo = new NeedTypeRepository(new HybridSessionBuilder()); 
     return repo.GetAll(); 
    } 
} 

Antwort

3

Erstellen Sie ein separates Viewmodel mit den Daten, die Sie in Ihrer Ansicht benötigen. Das Modell in M ​​von MVC ist nicht dasselbe wie das Domänenmodell. MVC-Ansichtsmodelle sind dumme DTOs ohne Verhalten, nur Eigenschaften. Ein Domänenmodell hat so viel Verhalten wie möglich. Ein Domänenmodell mit get; set; Eigenschaften wird nur als ein Anti-Pattern namens "anemic domain model" betrachtet. Es gibt 2 Orte, an denen die meisten Leute die Ansichtsmodelle platzieren: in der Web-Ebene, in der Nähe der Ansichten und Controller oder in einer Anwendungs-Service-Ebene.

Edit:

Wenn Sie nur eine Liste aller needtypes in der Datenbank und eine Anfrage in der Ansicht angezeigt werden müssen, würde ich in der Tat ein Ansichtsmodell mit der Anforderung erstellen und der Liste des needtypes als Eigenschaften. Ich glaube nicht, dass ein Aufruf mehrerer Repositorys in einem Controller ein Geruch ist, es sei denn, Sie haben eine größere Anwendung und Sie möchten möglicherweise eine separate Anwendungsdienstschicht, die das gesamte Viewmodel mit einem Methodenaufruf zurückgibt.

Ich denke, es könnte auch eine gute Idee sein, den Rat von Todd Smith über Wertobjekt zu folgen. Wenn die Bedarfstypen zur Laufzeit von Benutzern hinzugefügt oder bearbeitet werden können, sollte der Typ "needtype" eine Entität sein. Wenn die Bedarfstypen fest codiert sind und nur mit neuen Releases des Projekts geändert werden, sollte Needtype ein Wertobjekt sein und die Liste der Bedarfstypen könnte durch etwas wie NeedType.GetAll() aufgefüllt und in der Datenbank gespeichert werden, indem der Request-Tabelle eine Spalte hinzugefügt wird anstelle eines separaten Bedarfstabellen.

+0

Ein "anämisches Domänenmodell" ist nicht immer schlecht. Zum Beispiel können sich meine Validierungsregeln für ein Domänenobjekt je nach dem Prozess, in dem sie verwendet werden, ändern. Wenn meine Validierungsregeln von meinem Modell getrennt sind, macht dies das Modell anämisch und gleichzeitig konfigurierbarer. –

+0

Ein Domänenmodell bezieht sich nicht nur auf Entitäten. Auch Factories, Value-Objekte, Repositories, Domain-Services (nicht Anwendungsdienste wie ein Authentication-Service) sind Teil der Domain. Ich benutze die Validierung an verschiedenen Orten und für verschiedene Zwecke, aber das bedeutet nicht, dass ich mein Domänenmodell anämisch machen muss. – Paco

+0

Es geht um objektorientierte Programmierung versus prozedurale Programmierung. – Paco

1

Wenn es aus einer Liste kommt, dann ist dieses Ich wette, ist ein Fremdschlüssel. Denken Sie beim Entwerfen Ihres Domänenmodells nicht an Ihre Benutzeroberfläche. Dies ist einfach ein Fall, in dem NeedType ein Fremdschlüssel ist. Ersetzen Sie die Zeichenfolge NeedType durch einen Verweis auf ein tatsächliches NeedType-Objekt. In Ihrer Datenbank wäre dies ein Verweis auf eine ID.

Wenn Sie Ihre Liste der NeedType-Optionen erstellen, müssen Sie einfach jeden NeedType ziehen. Vielleicht ist es eine gute Idee, es im Cache zu behalten, wenn es sich nicht viel ändert.

+0

Ich verstehe, was Sie sagen (es gibt Überlegungen im Zusammenhang mit der Migration von Daten aus einer früheren Version, die mich veranlasste, den Text anstelle der ID zu speichern). Da diese Tabelle nur dazu dient, die Listen im Formular editierbar zu machen, war ich mir nicht sicher, ob sie in das Domänenmodell gehörte. – Leslie

1

Ihr NeedType sieht für mich wie ein Wertobjekt aus. Wenn es sich um schreibgeschützte Daten handelt, sollte es als Wertobjekt in einer DDD-Architektur behandelt werden und Teil Ihrer Domäne sein.

Eine Menge Leute stoßen auf das Problem "Omg so viel Redundanz", wenn Sie mit DDD umgehen, da Sie nicht mehr den alten Ansatz Datenbank -> DataTable -> UI verwenden.

+0

Dies ist, wie ich es eingerichtet habe. Ich war mehr besorgt über die Redundanz in dem Sinne, dass jede Liste genau dieselben fünf Eigenschaften haben wird. Ich könnte sie von einem Basistyp erben lassen, aber dieser Basistyp betrifft Listen in der Ansicht, nicht wirklich die Domäne. Ich dachte, es könnte einen anderen Weg geben, dies aufzustellen. – Leslie