2010-04-27 22 views
12

我正在使用S#arp架構,但我不記得自己在哪裏讀過它,但他們說他們的ViewModels應該存儲在服務層,並且您的視圖應該將視圖模型提交給服務進行處理。哪一層應該構建一個視圖模型?

我的問題是這樣的。哪一層應該構造ViewModel?它應該在服務層,並且控制器要求它嗎?或者控制器應該自己構造它?還有一個關於更新視圖模型的問題,就好像它包含集合,並且模型狀態無效,您還需要重新生成任何列表。

有什麼建議嗎?

非常感謝

馬特

回答

8

創建視圖中的控制器模型。控制器獲取域實體(通過模型綁定器從數據庫中檢索),可能位於其他視圖模型中,聯繫存儲庫以獲取其他數據,創建新視圖模型並將其傳遞給適當的視圖(或重定向)。所以控制器的責任是根據輸入域數據準備視圖/視圖模型(並且當然處理錯誤)。

您可以看看here,以替代在控制器中創建視圖模型。這種技術將視圖模型創建移動到動作之外,這樣不僅控制器動作接受純域對象,而且還返回純域對象。我不會說在所有情況下它都是合適的,但學習起來非常有趣。

以上與AutoMapper相關的技術也引發了類似於「我應該將視圖模型傳遞給服務層」的問題。不,你不知道。如果您需要將複雜對象傳遞給服務或域圖層,請在相應的服務/域圖層中定義此對象,然後使用它將數據傳遞到這些圖層。這個對象可以很容易地映射到/從視圖模型(例如,使用AutoMapper)。但是你的低層(服務/域)不應該耦合到上層(視圖/控制器)。不是在這種情況下,不在其他人中。從來沒有低層次的圖層應該依賴於它們上面定義的東西

+0

那差不多就是我現在做的,但我必須做的事情錯誤,因爲當把視圖模型轉回到域時,我似乎有很多條件邏輯。也許我需要將我的觀點分解成更小的塊。 – 2010-04-29 09:04:15

+0

我目前有一個編輯視圖,它根據實體的狀態添加適配。我會爲不同的州創建多個視圖更好嗎? – 2010-04-29 09:05:29

+0

沒有看到您的編輯視圖和模型,這很難回答。 – queen3 2010-04-29 10:27:56

3

這些文章可能是有趣的你:

DDD : Command Query Separation as an Architectural Concept

Better Application Services and CQS using S#arp Architecture

有與在服務層的視圖和表單模型第二製品相關的示例應用程序,而不是控制器。

+1

這是正確的答案。但是,我通常從控制器中的ViewModel開始,隨着控制器的發展將其遷移到服務層。 – 2010-07-01 22:15:41

+0

鏈接在moent下,也許http://sharp-architecture.readthedocs.io/en/latest/additional-resources/additional-information.html會有幫助嗎? – kristianp 2017-07-13 00:24:53

0

也看看Who Can Help Me - 這太棒了。這個框架基於S#arp架構。它有很多關於View/Form/Edit viewModel的指導。

11

根據傳統方法或理論上的明智,ViewModel應該是用戶界面層的一部分。至少這個名字是這麼說的。

但是當你開始用Entity Framework,MVC,Repository等自己實現它時,你會意識到其他的東西。

有人必須將實體模型與ViewModel進行映射(最後提到的DTO)。這應該在A)UI層(由控制器)還是在B)服務層完成?

我使用選項B.選項A是一個不可能的,因爲幾個實體模型組合在一起形成ViewModel的簡單事實。我們可能不會將不必要的數據傳遞到UI層,而在選項B中,服務可以使用數據進行播放,並且在映射(到ViewModel)後僅將所需/最小值傳遞到UI層。但是,讓我們假設我們使用選項A,將ViewModel放入UI層(以及Service層中的實體模型)。

如果服務層需要映射到ViewModel,那麼服務層需要訪問UI層的ViewModel。哪個圖書館/項目? Viewmodel應該位於UI層的單獨項目中,並且該項目需要由服務層引用。如果ViewModel不在單獨的項目中,那麼就有循環引用,所以不行。服務層訪問UI層看起來很尷尬,但我們仍然可以應付它。

但是如果有另一個UI應用程序使用此服務呢?如果有移動應用程序會怎麼樣? ViewModel有多不同?服務應該訪問相同的視圖模型項目嗎?或將所有的UI項目競爭?

經過這些考慮,我的答案是將Viewmodel項目置於服務層。無論如何,每個UI層都必須訪問服務層!並且可能會有很多類似的ViewModel,他們都可以使用(因此映射對於服務層來說變得更容易)。現在映射是通過linq完成的,這是另一個好處。

最後是關於DTO的討論。還有關於ViewModels中的數據註釋。帶有數據註釋的ViewModels不能駐留在服務層中。那麼DTO將是ViewModel的精確副本,並且兩者之間有一對一的映射關係(比如AutoMapper)。 DTO仍然具有用於UI(或多個應用程序)所需的邏輯並駐留在服務層中。 UI層ViewModel只是複製DTO中的數據,並添加了一些「行爲」(例如:屬性)。

雖然沒有直接關係到這個問題。 「視圖模型外牆」在此提到必須注意channel 9 link(另一視圖模型內部視圖模型)&「命令」也值得探討(@ 11:48啓動)

相關問題