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