在ASP.NET MVC项目中实现数据库存储库时,将业务逻辑放入其中是正确的还是将逻辑放在控制器类中可能更好?或者使用额外的服务和帮助器类来操作数据?
发布于 2011-10-16 10:35:09
归根结底,除了它自己的层(作为“模型”层的一部分)之外,没有一个完美的地方来放置您的业务逻辑。通常情况下,您可以使用不同的实现,但在每种情况下都有权衡。
为业务逻辑创建另一个层的折衷是,您必须实际封装代码。如果您过于激进,您可能还会在实体和域模型之间得到一些重复(如果您的DB的关系语义已经处理了您的业务逻辑)。
视图
视图是应用程序中最脆弱的部分,因为它是最有可能发生变化的部分。
由于必须支持所有不同的视图状态转换,因此在视图中使业务逻辑正确也是非常困难的。
现在大家都知道你根本不会这么做:)
存储库
这里的问题是抽象的维护性和纯洁性。违反这一点可能会让人们感到困惑,并使您的应用程序难以维护。
来自the P of EAA article on the Repository pattern
存储库在域和数据映射层之间充当中介,其作用类似于内存域对象集合
存储库是一种抽象,它将您的数据存储呈现为保存域对象的集合。
任何域逻辑都不应该驻留在其中。相反,它应该存在于您的域对象中(根据定义,您的业务逻辑就是您的域)。
否则(让您的存储库执行双重任务并验证域逻辑)将违反SRP (Single Responsibility Principle),并且将是一种代码气味。
您可以使用更高级别的域对象来使用域对象的集合来验证域逻辑(例如,对象集合中的依赖关系、大小限制等)。他们仍然会在幕后使用你的存储库来完成域对象的最终存储/检索,所以他们不会做双重工作(所以不会违反SRP)。
控制器
控制器也不是放置业务逻辑的好地方。控制器的工作是在控制器和模型之间进行协调。
模型是域,域是您的业务逻辑。
实体
您可以考虑将域数据放入实体中。
但是,如果实体是附加的,则在访问导航属性时必须小心,因为您可能会触发无意的DB查询或异常(取决于您的上下文是否被释放)。分离它们也是一个问题,因为它会破坏您的对象图,除非您在从上下文中分离对象后显式地将它们重新附加到彼此。
如果您创建单独的域模型类,则可以考虑仅将实体视为DTOs。
编辑: IValidatableObject
我刚刚发现了Entity Framework4.1中的一个特性,您可能想了解一下:IValidatableObject接口。
您可以使实体成为分部类,并在分部类中实现此接口。当您这样做时,实体框架将在保存时调用Validate,您可以在任何有意义的时候调用Validate。
这可能有助于避免在其他情况下将持久性模型从域模型中分离出来。
请参阅本文:http://msdn.microsoft.com/en-us/data/gg193959
旁注:视图/视图模型
如果您正在考虑这个问题,我建议您避免将实体传递回视图的诱惑。它会在很多情况下中断(例如,存储视图状态的Javascript序列化),并在其他情况下导致无意的DB查询。取而代之的是传递回简单类型(字符串、整数、列表、哈希集、字典等),或者构造视图模型类以传递给视图。
发布于 2011-10-15 20:40:52
添加服务层以将模型传递到Repository,可以在其中添加与控制器相对应的服务类。例如,如果使用UserController和用户模型,则可以将用户模型传递给UserService类。
在这里,服务层可以充当存储库和控制器之间的桥梁,从而很好地建立了控制器和存储库的分离。
发布于 2011-10-15 20:19:26
https://stackoverflow.com/questions/7777770
复制相似问题