14

在我的ASP.NET MVC應用程序中,我使用工作單元和存儲庫模式進行數據訪問。從哪裏轉換業務模型到查看模型?

使用工作單位類和它內部定義的存儲庫我在我的控制器中獲取相關的實體集。憑藉我的初學者知識,我可以想出兩種方法來獲取業務模型並將其轉換爲查看模型。

  • 庫返回的經營模式控制器,這種模式比映射到查看模式,或
  • Repository自身轉變經營模式來查看模型,然後將其返回到控制器。

目前我正在使用第一種方法,但我的控制器代碼開始看起來很醜,很長的視圖模型有很多屬性。另一方面,我想,因爲我的倉庫被稱爲UserRepository(例如),它應該直接返回業務模型,而不是某些僅用於單一視圖的模型。

對於大型項目,您認爲哪種方法更好?有其他方法嗎?

謝謝。

+1

我的[回覆] [1]這個問題應該解釋一下如何做得更好。 [1]:http://stackoverflow.com/questions/3747383/best-practices-to-partition-model-code-to-logical-parts-in-mvc-which-is-the- bes/3747474#3747474 – 2012-07-13 12:06:48

回答

20

庫應該返回域模型,無法查看模型。就模型和視圖模型之間的映射而言,我個人使用AutoMapper,所以我有一個單獨的映射層,但是此層是從控制器調用的。

下面是一個典型的GET控制器動作可能什麼樣子:

public ActionResult Foo(int id) 
{ 
    // the controller queries the repository to retrieve a domain model 
    Bar domainModel = Repository.Get(id); 

    // The controller converts the domain model to a view model 
    // In this example I use AutoMapper, so the controller actually delegates 
    // this mapping to AutoMapper but if you don't have a separate mapping layer 
    // you could do the mapping here as well. 
    BarViewModel viewModel = Mapper.Map<Bar, BarViewModel>(domainModel); 

    // The controller passes a view model to the view 
    return View(viewModel); 
} 

這當然可以通過自定義操作過濾器被縮短,以避免重複映射邏輯:

[AutoMap(typeof(Bar), typeof(BarViewModel))] 
public ActionResult Foo(int id) 
{ 
    Bar domainModel = Repository.Get(id); 
    return View(domainModel); 
} 

的自動地圖定製動作過濾器訂閱OnActionExecuted事件,攔截傳遞給視圖結果的模型,調用映射層(在我的情況下爲AutoMapper)將其轉換爲視圖模型並將其替換爲視圖。該視圖當然強烈地鍵入到視圖模型中。

+0

ty非常。不知道Automapper。這是我的問題所需要的。 – 2012-07-13 12:22:03

+0

自定義操作篩選器方法是否可測試?如果這是從單元測試中調用的,自動映射器如何工作? – 2014-01-08 20:30:34

+1

@JoshuaBarker,單元測試的重點在於你正在孤立地測試一個功能。那麼你究竟想在這裏單獨進行測試? AutoMap屬性?太好了,繼續爲它寫一個單元測試。或者你的控制器行爲將域模型傳遞給視圖?太好了,繼續爲它寫一個單元測試。或者您的控制器操作使用AutoMap屬性進行裝飾的事實?太好了,繼續爲它寫一個單元測試。到目前爲止,您已經編寫了3個單元測試,包含您需要的所有內容,以驗證您的控制器操作將按預期工作 – 2014-01-08 21:19:42

2

我認爲你的倉庫應該返回商業模式。

然後,您可以使用像Automapper這樣的工具自動將屬性映射到您的視圖模型,並且可以擺脫手動映射代碼。如果您不想公開所有業務權限的屬性,或者該視圖具有複合結構,則此方法非常有用。

你也可能會發現這個post有幫助,你可以擺脫手動映射調用(排序),它也提供了一個很好的例子,如何使用viewmodels等(在我看來) - 或者至少得到某種的靈感。從崗位

摘錄(屬性執行轉換形式busioness模型視圖模型):

[AutoMap(typeof(Product), typeof(ShowProduct))] 
public ActionResult Details(int id) 
{ 
    var product = _productRepository.GetById(id); 

    return View(product); 
} 
+0

ty非常。達林的回答有點詳細,所以我接受了他的回答。希望你不介意。 – 2012-07-13 12:21:15

+0

謝謝,那很好。感謝您的信息 - 我同意Darin的答案具有相同的內容,但呈現更好(因此是更好的答案)。我仍然會建議你閱讀鏈接,因爲可能有其他有趣的信息在Viewmodels等 – 2012-07-13 12:28:40

+0

謝謝。我現在正在閱讀它:) – 2012-07-13 12:39:16