Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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
C# 使用存储库时,ASP.NET MVC中的业务逻辑的最佳位置是什么?_C#_.net_Asp.net_Asp.net Mvc_Design Patterns - Fatal编程技术网

C# 使用存储库时,ASP.NET MVC中的业务逻辑的最佳位置是什么?

C# 使用存储库时,ASP.NET MVC中的业务逻辑的最佳位置是什么?,c#,.net,asp.net,asp.net-mvc,design-patterns,C#,.net,Asp.net,Asp.net Mvc,Design Patterns,在ASP.NET MVC项目中实现数据库存储库时,将业务逻辑放在其中是否正确,或者将逻辑放在控制器类中是否更好?或者使用其他服务和帮助程序类来操作数据?业务逻辑应该在您的域模型中 请调查这个答案 添加服务层以将模型传递到存储库,在存储库中可以添加与控制器对应的服务类。例如,如果使用UserController和用户模型,则可以将用户模型传递给UserService类 在这里,服务层可以充当存储库和控制器之间的桥梁,从而很好地建立了控制器和存储库的分离 我认为这取决于业务逻辑。是基于输入和输入规则

在ASP.NET MVC项目中实现数据库存储库时,将业务逻辑放在其中是否正确,或者将逻辑放在控制器类中是否更好?或者使用其他服务和帮助程序类来操作数据?

业务逻辑应该在您的域模型中

请调查这个答案


添加服务层以将模型传递到存储库,在存储库中可以添加与控制器对应的服务类。例如,如果使用UserController和用户模型,则可以将用户模型传递给UserService类


在这里,服务层可以充当存储库和控制器之间的桥梁,从而很好地建立了控制器和存储库的分离

我认为这取决于业务逻辑。是基于输入和输入规则验证的逻辑,如果是这样,最好是在模型上。但是,如果是基于工作流的业务规则,则可能需要在控制器中,例如,用户选择选项a,然后重定向到与选择选项B不同的页面/表单。如果业务规则必须处理数据持久性,那么它可能需要放在存储库中(对我来说放在那里似乎很奇怪)。关于这一点有很多讨论,但归根结底,这取决于您或您的团队对最终产品基于实现的可维护性和灵活性的看法。

我同意上述观点,控制器不应该仅仅为了返回适当的视图而对业务逻辑负责。我使用服务层来提供业务逻辑和视图模型创建,以便控制器将从服务返回的模型简单地传递给视图


我还确保我的视图模型是简单的DTO,服务只知道如何适当地填充属性。

最终,除了它自己的层(作为“模型”层的一部分)之外,没有一个适合您的业务逻辑的完美位置。通常,您可以使用不同的实现,但在每种情况下都有权衡

为业务逻辑创建另一层的代价是,您必须实际封装代码。如果您的攻击性太强,那么您的实体和域模型之间可能会有一些重复(如果您的数据库的关系语义已经考虑到了您的业务逻辑)

查看

视图是应用程序中最脆弱的部分,因为它是最有可能改变的部分

由于必须支持所有不同的视图状态转换,因此在视图中很难获得正确的业务逻辑

现在大家都知道,你就是不这么做:)

存储库

这里的问题是抽象的维护和纯度。违反这一点会让人困惑,并使你的应用程序难以维护

发件人:

存储库在域和数据映射层之间进行中介,就像内存中的域对象集合一样

存储库是一种抽象,它将数据存储表示为一个包含域对象的集合

不应在其中驻留任何域逻辑。相反,它应该存在于您的域对象中(根据定义,因为您的业务逻辑就是您的域)

否则(使您的存储库承担双重职责,并验证域逻辑)将违反SRP(),并且会产生代码气味

您可以使用更高级别的域对象与域对象集合一起工作,以验证域逻辑(例如对象集合中的依赖项、大小限制等)。他们仍然会秘密地使用您的存储库来进行域对象的最终存储/检索,因此他们不会承担双重责任(因此不会违反SRP)

控制器

控制器也不是放置业务逻辑的好地方。控制器的工作是在控制器和模型之间进行调解

模型是域,域是您的业务逻辑

实体

您可以考虑将域数据放在实体中。

但是,如果附加了实体,则在访问导航属性时必须小心,因为可能会触发意外的DB查询或异常(取决于是否释放了上下文)。分离它们也是一个问题,因为它会破坏对象图,除非在将对象从上下文中分离后显式地将它们彼此重新附着

如果你做了单独的域模型类,你可以考虑只处理实体。

编辑:IValidatableObject

我刚刚发现EntityFramework4.1中的一个特性,您可能想查看它:
IValidatableObject
接口

您可以使实体成为分部类,并在分部类中实现此接口。当您这样做时,实体框架将在保存时调用
Validate
,您可以在任何有意义的时候调用
Validate

这可能有助于避免在其他情况下将持久性模型与域模型分离

见本文:

旁注:视图/视图模型


如果您正在考虑,我建议您避免将实体传递回视图的诱惑。它在很多情况下都会中断(例如,Javascript序列化以存储视图状态),并在其他情况下导致无意的DB查询。而是传回简单类型(字符串、整数、列表、哈希集、字典等),或构造视图模型类以传递给视图。

+1;在我发布我的答案后读这篇文章。更简洁,尽管观点相同:)谢谢你的回答!有一个问题:如果我们将业务逻辑放在模型类中,我们是否应该像对待ViewModel那样看待模型(类似于WPF)?@Alexander:有一些相似之处,是的。但我