Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 在MVC分层应用程序中正确定义和设计业务、域和视图模型_Asp.net Mvc 3_Design Patterns_Models_Layered - Fatal编程技术网

Asp.net mvc 3 在MVC分层应用程序中正确定义和设计业务、域和视图模型

Asp.net mvc 3 在MVC分层应用程序中正确定义和设计业务、域和视图模型,asp.net-mvc-3,design-patterns,models,layered,Asp.net Mvc 3,Design Patterns,Models,Layered,我在C#和Razor中有一个ASP.NETMVC3。应用程序的体系结构分为数据访问层(EF类+存储库)、服务层、控制器、视图模型和视图 我的应用程序是一个仪表板,它必须使用图形显示有关产品的统计信息 假设我有Product和ProductCategory表格,并且在一个图表中,我必须显示每个ProductCategory每个月售出的产品的百分比。在x轴上我有月份,在y轴上我有百分比ProductPerCategory/ProductTotal,因此我有与ProductCategories一样多的

我在C#和Razor中有一个ASP.NETMVC3。应用程序的体系结构分为数据访问层(EF类+存储库)、服务层、控制器、视图模型和视图

我的应用程序是一个仪表板,它必须使用图形显示有关产品的统计信息

假设我有
Product
ProductCategory
表格,并且在一个图表中,我必须显示每个
ProductCategory
每个月售出的
产品的百分比。在x轴上我有月份,在y轴上我有百分比ProductPerCategory/ProductTotal,因此我有与
ProductCategories
一样多的行

在这种情况下,我的域模型由EF上的
Product
ProductCategory
对象创建。我的存储库将这些域对象提供给其上层(服务层)

我的业务模型
ProductGraph
对象创建,我的服务层将此业务对象交给其上层(控制器)

我的控制器将此
ProductGraph
对象映射到视图中要显示的视图模型
ProductGraphViewModel


模型之间的这种区别正确吗?在定义层间传递的对象时,有什么不足或不好的方法吗?

好吧,我的门外汉都很赞成,这似乎很标准。其他一些需要考虑的事情是:1)您的DAL/服务层接口吗?2)是否使用依赖项注入(将这些接口传递给控制器实例化)?这样,您就可以轻松地切换实现或模拟单元测试


这可能很有趣。

我会问几个我自己的问题来回答你的问题

  • 您对“域模型”和“业务模型”的区别是什么?每一个都比另一个有更多/更少的价值吗?不知道更多,我会假设他们是同一件事

  • 您的服务层有什么好处?人们(包括我自己)经常陷入“服务层”陷阱,而实际上它只是包装了您的存储库方法。最终,您会将ORM细节泄露给消费层,从而首先破坏了您的抽象点

  • 如果您给我们一些层间示例流的代码,可能会有所帮助


    是的,@sweaver2112对使用DI很在行。简单的设置,最大的好处。

    感谢您的回复!我使用存储库和服务层之间以及服务层和控制器之间的接口。通过这种方式,我可以轻松地更换符合接口的组件。假设我有
    IRepository
    我可以创建一个
    FakeRepository
    组件来实现
    IRepository
    。我将使用NUnit,但我对DI是新手。这就是你的意思吗?是的,就是这个。:)许多模拟框架甚至无法工作,除非您想要模拟的是一个接口。想想看,这是有道理的……然而,我怀疑的是在服务层创建的业务模型。它在与域模型相关的过程之后“包装”数据。该对象与视图模型对象非常相似。这是一个好的实践吗?如果一个完全独立的、一流的视图模型看起来有些过分,您可以使用ViewData、TempData和ViewBag来存储额外的数据,而无需创建新的类-但不确定这是否是一个好的设计。我不使用ViewData,TempData和ViewBag,因为它们是在后台工作的,我无法测试它们的行为,请回答。1)我认为是域模型,描述应用中涉及的实体的模型。我将应用程序特定功能(在本例中为仪表板)中涉及的所有实体定义为业务模型。业务模型由服务层创建,域模型严格依赖于数据源。2) 应用程序的边界没有很好地定义。它必须成为一个门户,这就是为什么我使用服务层,以便在必须实现新需求时最小化代码修改。请把你的名字给我feedback@CiccioMiami-您不能像这样尝试“证明未来”您的应用程序。您投入了额外的精力,这不仅使您的应用程序更加复杂,而且可能是浪费精力。构建健壮、定义良好且简单的代码,只需满足它的需要。然后,当你需要改变的时候,再做决定。听起来您的业务模型除了投影一个域模型之外,根本没有增加任何价值。不管怎样,你的映射是一个ViewModel——那么“当前”的好处在哪里呢?我的建议?Repo将域/POCO传递给控制器,控制器映射POCO/视图模型。简单,容易,有意义。如果你需要为其他“客户”服务,那么创建另一个项目,它可以是一个Web API(即将发布的MVC4使这非常容易)。这可以直接调用到您的存储库中。如果您尝试使用一个通用的“服务”层来尝试“一切”,它将变得庞大。为特定的需求创建特定的模块。你是对的,但是这样当我需要为应用程序添加另一个功能时,我可以创建另一个服务层(我认为这是一个很好的方法,我依赖于你的经验)。此外,对于您的解决方案(带有POCOs的存储库-控制器),我必须执行直接在控制器中创建统计信息所需的业务逻辑。“我知道保持控制器苗条是一个很好的做法。”CiccioMiami说。我使用controller->repo。在你的位置上,保持控制器苗条是一个很好的做法。我的是,因为我使用管道和过滤器技术。我的一个示例操作可能如下所示:
    var question=\u repository.Find().Questions().ThatAreVisible().writenbythisuser(userId);返回视图(Mapper.Map(问题))