我正在尝试用ASP.Net学习MVC并正在阅读Steve Sanderson的书。我很困惑的一件事是在哪里放置业务逻辑?
例如,删除产品时,所有Sanderson都有一个CartController中的方法,该方法调用productsRepository上的Delete方法。这对我来说很奇怪,因为如果有任何业务逻辑,例如确保产品不在任何人的购物车中,等等,则必须在产品库或CartController中。
这两者似乎都是放置业务逻辑的坏地方;产品存储库可以很容易地被另一个替换(从使用数据库转换为使用会话),使用Controller意味着您将业务逻辑放在UI层中。
他不应该使用包含业务逻辑的类并调用存储库的delete方法吗?存储库是业务逻辑类'?
的成员变量答案 0 :(得分:8)
我通常以类似于以下的方式构建我的MVC解决方案:
其中一些可以合并,但将它们分开可以更容易地找到东西,并确保您的图层边界得到尊重。
显示产品购物车的典型控制器操作可能如下所示:
public virtual ActionResult ProductCart()
{
var applicationService = <obtain or create appropriate service instance>
var userID = <obtain user ID or similar from session state>
var viewModel = applicationService.GetProductCartModel( userID );
return View( "Cart", viewModel );
}
将产品添加到购物车的典型控制器操作可能如下所示:
public virtual ActionResult AddProductToCart( int productID )
{
var domainService = <obtain or create appropriate service instance>
var userID = <obtain user ID or similar from session state>
var response = domainService.AddProductToCart( userID, productID );
return Json( new { Success = response.Success, Message = response.Message } );
}
答案 1 :(得分:3)
我还阅读了Sanderson的第一个版本的书,这很棒 - 一个非常简单的方法来选择并开始使用ASP.NET MVC。不幸的是,你不能直接从他的书中的概念跳到编写一个大型可维护的应用程序。最大的障碍之一是找出将业务逻辑和其他问题放在UI和持久存储之间的位置(称为Separation of Concerns或SOC)。
如果您有兴趣,请考虑阅读Domain Driven Design。我不会建议我完全了解它,但它可以很好地从Sanderson的示例应用程序过渡到成功区分UI问题,业务逻辑和存储问题的东西。
我的解决方案有一个单独的服务层。控制器与服务层通信(使用依赖注入 - Ninject)。服务层可以访问我的域对象/业务逻辑和我的存储库(NHibernate - 也可以使用Ninject进行调整)。我的视图或控制器中的逻辑非常少 - 控制器用于协调器的目的,我努力使控制器的操作尽可能地薄。
我的域层(实体,业务逻辑等)没有依赖关系。它没有引用我的Web项目或我的Repository项目。它通常被称为POCO或Plain Old C#/ CLR对象。
编辑:我在你的一条评论中注意到你正在使用EF。 EF不支持POCO而不使用名为Code First的东西(去年8月我检查时处于社区技术预览状态)。仅供参考。
答案 2 :(得分:1)
现实情况是,这个答案没有灵丹妙药,这本质上是一个背景问题。我喜欢尽可能地分离事物,如果你考虑它,业务逻辑就是应用程序中的另一层。
我编写了一个受BDD启发的决策引擎,并将其作为可通过NuGet提供的OSS项目发布。该项目名为NDecision,您可以在NDecision project home page上阅读。
NDecision使决策树业务逻辑的实现变得非常简单,如果您是Gherkin语法和Fluent编码实践的粉丝,您会感到宾至如归。下面的代码快照来自项目站点,并演示了如何实现业务逻辑。
这对你来说可能不是一个解决方案,但是这个想法是,如果你已经在一个集合中拥有你的域模型 - 这是一个很好的想法和常见的做法,如前面的另一个答案中所建议的那样,没有理由你不能拥有与你的“决策树”的另一个集会。编写NDecision是为了将逻辑分成一个独立的层。
希望这会有所帮助。
答案 3 :(得分:0)
如果您想要可扩展性,直接从GUI使用数据访问对象是不好的做法。所以在你提到的例子中,我认为你应该用一些支持业务操作的业务逻辑类替换直接读取或写入数据库的存储库。
答案 4 :(得分:0)
我正在尝试用ASP.Net学习MVC 我在读史蒂夫桑德森的书。 我很困惑的一件事是在哪里 放置业务逻辑?
在模型中(MVC中的M)或域层。这些是一组独立的类型(最好是在一个单独的项目中),它们代表域模型,服务和存储库。