我想使用EF 6 Code第一概念在ASP.NET MVC 5中创建一个好的应用程序。我希望它设计得很好,即一般来说:表示,逻辑和数据层是分开的。我希望它可以测试:)
这是我的想法以及与创建应用程序相关的一些问题
表示层:这是我的整个MVC - 视图模型(不是模型),视图,控制器 我认为验证应该在其他地方完成(在我看来 - 它是业务逻辑的一部分)但是在ViewModelds中使用DataAnnotations命名空间中的属性并在控制器中检查验证是非常方便的。
逻辑层:服务 - 具有规则业务逻辑接口的类。 我把那些函数放在:AddNewPerson(PersonViewModel Person),SendMessageToPerson(...)。 他们将使用数据库上下文来进行操作(有可能并非所有人都依赖于上下文)。服务和db之间有直接连接 - 我的意思是服务类有引用做上下文。 我应该在ViewModel和Model之间进行映射?我听说服务对它来说是一个不好的地方 - 所以也许在控制器中。我听说服务应该专门做与db相关的工作。 这样对吗?我的服务层图片好吗?
数据层:我已经详细了解了Repository和UoW模式。有一些文章表明EF6实现了这两件事。如果不需要这样的行为,我不想创建额外的代码。问题是:我是否认为我不需要它们?
这是我的流程:
查看< - >控制器(使用ViewModels)< - >服务(使用模型)< - > DB。
**我将在我的项目中使用DI。
您如何看待我的项目结构?
答案 0 :(得分:3)
如果您不需要创建通用数据访问机制,则没有理由在Entity Framework中使用工作单元模式。你只会这样做:
如果不是这种情况,您很可能不需要自定义工作单元。另一方面,存储库可能很有用......但是使用EF6还可以获得存储库的许多好处,因为EF6提供了用于测试的模拟接口。无论如何,请远离通用存储库,除非它只是您具体存储库的实现细节。将通用存储库暴露给其他层是一个巨大的抽象泄漏...
我总是使用Repository / Service /Façade模式来创建数据和业务(以及UI和业务)层之间的分离。它提供了一种方便的模拟方法,无需模拟您的数据访问本身,它将您的逻辑与EF使用的Linq层引入的特定内容分离(Linq相对通用,但有些内容特定于EF), façade/ repository / server接口解耦了。)。
一般来说,你走在正确的道路上......但是,我要指出在视图模型上使用数据属性是一件好事。这会将您的验证集中在您的模型上,而不是让您将验证逻辑放在一起。
您在业务逻辑中也需要验证,这是正确的,但您的错误是假设您应该只在业务逻辑上使用它。您需要在应用程序的所有层进行验证。特别是,您的UI验证可能具有与业务逻辑验证不同的要求。
例如,您可以在UI中实施创建新帐户作为多步骤向导,这需要与业务层进行不同的验证,因为每个步骤仅包含总对象验证的子集。或者您可能要求您的移动界面具有与您的网站不同的验证要求(一个可能使用验证码,而另一个可能使用基于触摸的人工验证)。
无论哪种方式,重要的是要记住验证在客户端,服务器和各个层都很重要......
答案 1 :(得分:1)
好的,让我们澄清一些事情......
ViewModel
的概念(或ViewModel
的实际措辞)是由 Microsoft Martin Fowler引入的。事实上,ViewModel
只不过是一个简单的class
。
实际上,您的Views
被强类型为classes
。期。为避免混淆,提出了ViewModel
措辞来帮助人们理解
“此类,将由您的视图使用”
因此我们称之为ViewModel
。
此外,虽然许多书籍,文章和示例都使用ViewModel
这个词,但我们不要忘记它只不过是Model
。
事实上,你有没有注意到为什么MVC应用程序中有Models
文件夹而不是ViewModels
文件夹?
此外,您是否注意到在视图的顶部有@model
指令而不是@ viewmodel
指令?
那是因为一切都可以成为模特。
顺便说一下,为了清楚起见,我们非常欢迎您删除(或重命名)Models
文件夹并创建一个名为ViewModels
的新文件夹(如果有帮助的话)。
无论您做什么,最终都会在页面顶部调用@model
而不是@viewmodel
。
另一个类似的例子是DTO classes
。 DTO类只不过是常规类,但它们后缀为DTO
,以帮助人(程序员)区分所有其他类(包括View模型)。
在我最近开展的一个项目中,团队没有完全掌握这个概念,所以他们的Views
强烈输入Models
,而不是强烈输入DTO classes
。 IsVisible
。在理论和实践中,一切都在发挥作用,但他们很快发现,事实上他们在DTO中有ViewModel
等属性;这些属性应属于您的Service Layer
类,因为它们用于UI逻辑。
到目前为止,我还没有回答你的问题,但我确实有关于快速架构的类似帖子。您可以阅读帖子here
我想指出的另一件事是,当且仅当您的Service Layer
计划为其他事项提供服务时,例如Winform应用程序,移动网站等...然后ViewModels
不应该收到Service Layer
。
您的ViewModel
不应该知道什么是Controller
。它应该只接受,接收,发送等...... POCO课程。
这意味着,ActionResult
内ModelState
内Valid
ViewModel
Service Layer
后,您需要将Automapper
转换为POCO反过来,将被发送到ViewModel
。
换句话说,我使用/安装AddNewPerson()
nugget包并创建一些扩展方法,将Person
转换为POCO,反之亦然(POCO转换为ViewModel)。 / p>
这样,您的PersonViewModel
方法会为其参数收到if and only if
个对象,而不是接收Service Layer
参数。
请注意,这只是Service Layer
您的ViewModels
有效服务其他事项的计划......
如果情况并非如此,请随时让{{1}}接收,发送,添加等... {{1}}代替POCO。这取决于您和您的团队。
请记住,有许多方法可以给猫皮肤。
希望这有帮助。