MVC:在哪里放置业务逻辑?

首先,我看到了很多这方面的问题,但是背后还没有足够的推理。 如果我的问题不够好,应该删除,我会明白。

举个例子,我看了一个45 +投票答案,他build议你把商业逻辑放在模型中,这听起来很合理。

然而,我的第一个大型项目,我完全在控制器中完成了我的BL,因为我没有质疑这些事情,看看它是如何在AccountController中完成的,这是自动添加的,如果您select使用表单身份validation的MVC。 所有的方法看起来都很漂亮。 或者,也许这是可以添加的代码量最less,我忽略了一些东西?

一个在YouTube上的人问我是否把所有的逻辑放在他的模型中是正确的,起初我不是! 然后我开始想,也许他是对的!?

毕竟,我在哪里放置业务逻辑呢? 如果是在模型类中,那么在控制器的方法中应该考虑多less代码是一个健康的数量? 一行在控制器中最多从模型中调用某个方法,然后返回视图?

出于几个原因,我更愿意将域逻辑放在模型中。

  1. 该模型应该没有UI代码,因此更容易testing。 只要有可能,我希望在编写任何UI代码之前有一个完整的工作模式(意味着完整的testing覆盖率)。 控制器可以相信模型正在做正确的事情,只是处理UI的问题。

  2. 如果将域逻辑放在控制器中,那么在不同的应用程序之间甚至不同的控制器之间共享并不那么容易。

我喜欢保持我的模型干净即只是与属性和业务逻辑。 我总是认为把dependency injection到控制器中是很好的,而这些依赖包含了我在模型上执行的逻辑。 我喜欢在可能的情况下坚持单一责任原则,并且我发现有很多方法的模型很快就会膨胀起来。 对于两者都有利弊,注入大量的依赖关系有一定的开销,但是可以单独testing,并且保持简单的类,最终你会得到更精简的控制器。 尽pipe我的逻辑实际上并不存在于我的模型中作为类的成员,但它仍然是业务逻辑。 我倾向于没有在控制器中定义业务逻辑,因为嘲讽诸如Httpcontext这样的事情是有点噩梦和不必要的。

业务逻辑属于问题域,属于问题域的所有内容都转到MVC中的模型

控制器应负责将数据从模型传递到视图,从视图返回到模型。 因此,控制器是用户与之交互的桥梁,以及程序如何模拟和存储问题的状态。 可以这么说, pipe道

这里的关键是业务逻辑和pipe道逻辑之间的区别。 在我看来,自动生成的账户控制器所做的主要是pipe道工,而不是真正的业务逻辑。 请记住,pipe道逻辑不一定是短的,所以你不需要施加人为的限制(比如“在控制器中最多有X个呼叫”)。

我的团队从webforms(asp.net)迁移到mvc时做了大量的研究,并提出了以下结构。 据我所知,它不是关于应用程序的大小。 它关于保持代码清洁和清晰。

DALProject

 AccountsDAL.cs --- > Calls SP or any ORM if ur using any 

BLLProject

 AccountsBLL.cs ---> Calls DAL 

WebProject

 Model AccountsModel --- > Contains properties And call BLL Controllers IndexController ---> Calls Models and returns View Views Index 

控制器应该负责模型和视图之间的数据传递。 除此之外,不应该有任何不必要的代码。 例如,如果您正在login,应该在模型级而不是控制器上完成。

这个话题似乎有些混乱。 大多数情况下,人们似乎倾向于将MVC模式与N层架构混为一谈。 现实是这两种方法可以一起使用,但是一种不依赖于另一种,也不是必需的。

N层体系结构涉及将应用程序分成多个层。 一个简单的例子就是应用程序分为表示层,业务逻辑层和数据访问层。

MVC是处理应用程序表示层的devise模式。 完全有可能根据MVC方法devise应用程序,而不将业务逻辑和数据访问逻辑从表示层分离出来,从而最终实现单层devise。

结果是,如果您遵循MVC方法,而不将应用程序分成多个层,则最终会得到模型,视图和控制器,这些模型,视图和控制器将业务规则和数据访问逻辑与其余逻辑混合在一起。

根据定义,在N层体系结构中,表示层只能与业务逻辑层进行通信,因此应该认为任何MVC组件都只能与业务逻辑层进行通信。

如果您正在构build不涉及表示层的应用程序,而不是表示层,则不必关心MVC模式。 但是,你很可能仍然将你的应用程序分成多层,因此即使不涉及表示层,也可以遵循N层devise。

我喜欢保持模型清洁(参考:@Mark Walsh)。 无法重用embedded在控制器中的逻辑的问题很容易通过dependency injection来克服,或者,如果您认为太多的话,通过接口公开您的业务/域逻辑并使用控制器中的外观模式。 这样你就可以得到你所需要的function,但是保持控制器和模型都很干净。

我也宁愿保持模型清洁。 MVC控制器只能用于拨打电话,也应保持清洁。 因此,根据其可重用性,敏感性和相关性,可以写入业务逻辑

1.WebApi控制器:使用webapi控制器的优势在于,您可以将这些服务稍后作为服务公开给其他设备,使您的代码可重复使用。

2. BAL /共同的委托人:有一些逻辑具有特定的用法,不能作为api暴露,可以在这个类中推送。

3.存储库:所有与数据库相关的查询都被添加到一个存储库中。 可以有一个通用的存储库,将实现每个表的所有function(CRUD操作)或特定的存储库。 取决于要执行的操作。

一般来说,商业逻辑不应该存在于任何MVC玩家中, 它只应该被你的控制器动作所消耗

正如很多人所提到的,最好创build一个库来承载业务逻辑,作为一组客户端不可知的,可重用的组件。

通过这种方式,我们可以大大提高软件的可重用性,兼容性,可扩展性和可testing性。 我们也减less了对某些框架function的依赖,这使得更容易迁移到更新/不同的技术。

将我们的业务逻辑抽象成一个独立的程序集(或程序集),多年来一直为我们服务。 事实上,任何.NET技术(ASP.NET MVC / API / Core,WPF,Win Forms,WCF,UWP,WF,控制台等)都可以使用我们的业务逻辑。

另外,我们喜欢我们的中间层来处理业务规则和validation逻辑,以减less对.NET MVC框架的依赖。 例如,我们避免使用.NET MVCvalidation帮助,而是依靠我们自己的。 这是另一个让我们可以从任何.NET技术轻松使用我们的业务逻辑的因素。

以这种方式逻辑devise我们的中间层使我们能够轻松实现这种物理架构:

在这里输入图像说明

它是用Peasy.NET编写的, 多年来一直为我们服务。 事实上,我们决定开源。

如果有人对我们的中间层是什么样子感兴趣,下面是一个客户不可知论的业务层的样本 。 它还展示了多个.NET客户端(ASP.NET MVC,Web Api和WPF)的使用情况。

希望这可以帮助别人!

我知道这是一个有关MVC的问题,但我认为我给的例子(Web API)将是有用的。

我正在开发我的第一个Web API,并且正在重新使用来自其他应用程序的业务逻辑。 具体而言,它来自外部DLL,所以我的API只是用来与SAP解决scheme“交谈”,接收来自PO的请求并将响应发回。

我怎么能把我的逻辑(已经实现)到我的控制器? 我不需要它。 我的控制器将只接收,validation请求并撰写响应以发回数据。

我正在使用ViewModel类,他们必须拥有的只是一个映射函数,只是从TransferObjects(来自外部DLL)读取信息并转换为ViewModel。

我不熟悉我的应用程序(在这种情况下,Web API)持有业务逻辑,我认为重新使用性将会以这种方式丢失。

我把我的业务逻辑视为一种依赖,我注入到控制器中。

为了提供一个unit testing解决scheme,我已经做了大量的重构工作,我必须创build大量的接口,并在传统中实现一些devise模式来提供这个解决scheme。

在我看来,业务层必须是应用程序的一部分,最好在另一个类库中。 所以你将在你的应用程序中实现一个真正的分离概念。

当然,如果你的CORE(业务)是你的应用程序(API / WebSite) ,业务规则将被实现到你的MVC类中。 但是,将来如果你想开发一个新的应用程序和一些业务规则是相同的,我敢打赌,你将有很多问题,只是为了维护在这两个应用程序中实现相同的逻辑。