2011-12-17 82 views
1

這個問題真的有更大的建築影響,我歡迎任何意見或建議:如何將UI圖層資源文件附加到域模型數據註釋?

當談到OOP時,我更多的是馬丁福勒學派。我相信你應該能夠直接在UI中呈現域實體。如果我有一個Car實體,我應該可以將其呈現給網頁。領域模型是橫切的關注點,而不是圖層。將領域模型視爲一個層面導致貧血領域模型。我不相信OOP架構中的DTO。

我的視圖模型是一種組合視圖中所需的域實體的方法。這不是一個DTO。我不明白使用像DTO這樣的視圖模型的原因是什麼,儘管使用automapper似乎是一件常見的事情?

因此,使用元數據方法,我將數據註釋放在我的域模型上,以提供有關如何呈現和驗證實體的任何UI實現提示。我喜歡有一個richER域模型。

在MVC3中,如何使用駐留在UI層的資源文件完成此操作(特別是使用Display數據註釋)?是否有本地實施或我需要自己創作?或者我的方法在某處出錯了嗎?

回答

0

所以我結束了在域模型中放置資源文件並添加了一個自定義的HiddenFieldAttribute,這樣我就不必在域模型中引用MVC程序集。

我仍然從根本上不同意視圖模型是真正的DTO,並且領域模型應該被構建爲一個層。我覺得以這種方式構建應用程序會產生真正沒有價值的抽象。如果領域模型確實是一個層,那麼我們將構建一組訪問它的邏輯接口,而我們不這樣做。這是一個交叉問題。

感謝olivehour進行有趣的討論,並建議將資源文件放入域模型組件中。

1

我不同意。

首先,您將用來指定實體屬性應該如何顯示在網頁上的一些屬性來自System.Web命名空間,而不是System.ComponentModel.DataAnnotations命名空間。通過將這些屬性放在域模型中的屬性上,您的域模型正在對System.Web進行依賴。例如,有[HiddenInput]屬性告訴MVC3以輸入類型=「隱藏」來呈現字段。這不在System.CompoenentModel.DataAnnotations中。其次,我不相信你需要實體屬性上的數據註釋屬性才能擁有豐富的域模型。豐富的領域模型來自在上下文中包裝知識的類。客戶端應用程序不需要知道有關該域的任何信息就可以使用它。您可以通過使用無處不在的語言描述知識的類,方法和屬性來實現豐富的領域模型。 DataAnnotations屬性不適合無處不在的語言imo。而且,你的域名不僅僅是你的實體。您可以使用工廠,服務和其他模式來構建豐富的域模型。只有實體和元數據的域對我來說聽起來很貧乏。

第三,您可能有一個實體應該以不同的方式在您的網站上呈現。當有人搜索汽車時,您可能只想顯示品牌,型號,年份和縮略圖照片。當有人點擊搜索結果時,您可能想要顯示多張照片,評論等。如果您要在實體上使用UIHint屬性來告知網絡用戶如何呈現汽車,您將無法擁有在不同的環境下呈現不同的策略。

最後,是的,automapper真的非常適合將您的實體拖放到視圖模型中。它基本上允許您填充實體的副本,從域中斷開連接,針對特定的用戶界面問題。這裏使用HiddenInput和UIHint屬性來告訴MVC3如何呈現數據是安全的。

迴應置評1

至於UIHint,我提到在這裏,因爲它有MVC3 EditorTemplates特殊的意義。在部分視圖涉及接收輸入的情況下,視圖的組成是什麼?文本字段,下拉列表和輸入元素,通常對應於某些聚合根中的實體及其屬性。因此,您將需要一些實體的表示來封裝數據。您的DTO也可以是一個聚合根,並且具有深度。您可以擁有標量屬性(text/date/bool),導航屬性(下拉列表)和集合屬性(ul/ol/table)的根DTO。

我們爲聚合根中的許多實體創建相應的視圖模型,並使用EditorTemplates將它們實現爲視圖。如果我們想切換到不同的EditorTemplate,我們可以將UIHint應用到viewmodel屬性。因此,我們可以告訴它「將地理位置呈現爲谷歌地圖」。 Automapper可以將導航和集合屬性映射到相應的視圖模型,從而根據用戶需要形成複雜的域實體表示形式。

原諒我,如果我誤解你的意思是由平dto。

迴應置評2

一個ViewModel DTO可以拉平/非規範化(使用automapper)的一些屬性,如果您的需求呼喚它。例如,考慮一個大學實體。它可以有多種語言的名稱(翻譯),暗示一個大學名稱實體的總和,大學有一個名稱集合(1..n)。在這些名稱中,1可以表示官方名稱/本地名稱,另一個可以表示用戶的CurrentUICulture的翻譯名稱。集合中的其他實體可能代表用戶不理解的TranslatedNames,並且不需要打擾。

如果你有一個觀點,即只有在這2名在收集感興趣,可以促進他們對視圖模型一流的性能:

public class UniversityViewModel 
{ 
    public string OfficialName { get; set; } 
    public string TranslatedName { get; set; } 
    // ...other properties 
} 

這是反規範化的一部分的情況下,實體在轉換爲視圖模型時可以有意義。注意viewmodel是如何貧血的 - 這是一個從控制器到視圖的數據傳輸的裸容器。這非常好,事實上,我們鼓勵。

回答到原來的問題

要回答你原來的問題,它可以幫助,如果你認爲你的域模型的&實體層 - 更具體地說,底層。如果您將應用程序中的各種問題考慮爲與其他問題有關,則分層軟件更易於理解。 MVC3是一個演示/ UI層,並將依賴於它下面的圖層 - 其中一個是你的域圖層。

如果要從域層訪問UI中的資源文件,則需要採用相反的方向。你會根據更高層來製作低層。如果您的域lib依賴於資源的UI庫,並且UI lib依賴於實體的域,則最終會產生循環依賴關係。我認爲如果你需要的話,你可以用反射來完成它,但是在那種情況下,你會反對這個框架。如果是這樣的話,MVC和.NET一般可能不是您的最佳選擇。

我其實認爲資源文件是一個交叉問題。我們的應用程序已經遍佈了i18n,而且我們經常發現我們在域和UI中都需要相同的語言文本資源。

在實體上放置Display屬性沒有任何問題。但是如果你想爲它使用資源,那麼要麼將該資源放在域圖層中,要麼如果你覺得它不屬於那裏,則放在較低層。這樣它可以被域和UI訪問。

+0

嗨橄欖,感謝您的書面答覆。一些DataAnnotations在System.Web中是很好的一點。我會考慮這個。 – modelMan 2011-12-18 18:29:48

+0

第二點我基本同意,並且只是意味着DataAnnotations可以增加領域模型的豐富性,並且不會取代良好的建模技術和模式。第三,我將UIHint看作更多的默認腳手架。在不同的環境下,你仍然需要不同的視圖模型,但視圖模型是保持視圖的組成,而不是平坦的DTO imho。 – modelMan 2011-12-18 18:51:07

+0

我一般認爲DTO是數據的非規範化表示。這就是我的意思。當然,正如你指出的那樣,情況並非如此。 – modelMan 2011-12-19 00:43:39