为我的MVC应用程序创build一个服务层?

据我所知,MVC通过作为控制器的“粘合剂”将演示文稿(视图)中的类定义(模型)分开。 控制者应该有一个单一的责任,因此是可以testing的。 ViewModel用于将来自多个实体的数据汇总在一起,并从控制器中“按摩”数据以获得视图。

这似乎是业务逻辑没有真正的地方…所以我认为另一层服务将是合适的。 我只是不知道在哪里放置这个层,或者如何构build服务 – 它应该是一个叫做“services”的类,它包含一系列函数吗? 我对MVC有点新,所以任何阅读材料,样本或一般新人types的提示都会很棒。

开发ASP.NET MVC应用程序时,我通常使用服务层。 它类似于Martin Fowler在“企业应用架构模式”中讨论的服务层模式 。 它封装您的业务逻辑,使控制器非常薄。 基本上,控制器使用服务层来获得域模型,然后将其转换为视图模型。 我还使用“ 工作单元devise模式”来处理事务,并使用“ 存储库devise模式”来封装数据访问层,以便于进行unit testing,并能够轻松更换ORM。 该图显示了我在MVC应用程序中使用的典型图层。

MVC架构

服务层在此图中被标记为“应用程序或域层”,因为当您使用术语“服务层”时,我发现人们会感到困惑。 他们倾向于认为这是一个Web服务。 它实际上是一个可以被你喜欢的Web服务技术所使用的程序集,比如ASP.NET Web API或者WCF,还有一个控制器。

至于命名约定,我通常使用描述服务域后面的内容。 例如,如果我有一个处理用户成员资格的服务层,那么我将拥有一个名为MembershipService的类,该类具有控制器和Web服务所需的所有方法来查询和操作成员资格域。 注意你可能在同一个应用程序中有多个域,所以你可以有多个服务层。 我的意思是在这里,你不必有一个单一的服务,照顾整个应用程序。

我的build议是创build一个名为“服务”的单独的类。 将它们放在不同的类库(或名称空间)项目中,并使它们独立于MVC框架基础结构上。 我build议也使用某种dependency injection(最好的是构造注入)。 那么你的服务类可能看起来像:

public class MyService : IMyService { IFirstDependency _firstService; ISecondDependency _secondService; public MyService(IFirstDependency firstService, ISecondDependency secondService) { } public Result DoStuf(InputDTO) { // some important logic } } 

然后你从你的控制器中使用这些服务。 看这里的完整例子。

根据存储库 – 我的build议是,如果你打算使用一些现代的ORM(NHibernate,EntityFramework),不要使用它们,因为你的业务逻辑将被封装在服务层中,并且你的数据库已经被ORM框架封装了。

看看MSDN最佳实践中的文章 。

文章中的应用程序的源代码可以在这里find。

从“业务逻辑应该在服务中,而不是在模型中”引用? :

在MVP / MVC / MVVM / MV *架构中,根本不存在服务。 或者如果他们这样做的话,这个术语就是指任何可以注入控制器或视图模型的通用对象。 业务逻辑在你的模型中。 如果你想创build“服务对象”来编排复杂的操作,那么这就是实现细节。 可悲的是,很多人都是这样实现MVC,但是它被认为是一种反模式(Anemic Domain Model),因为模型本身什么都不做,只是UI的一大堆属性。

有些人错误地认为,采取100线控制器的方法,并将其全部投入到服务中,使得更好的体系结构。 它确实没有; 它所做的只是添加另一个可能不必要的间接层。 实际上,控制器还在做这个工作,只是通过一个名字很差的“帮手”对象来实现。 我强烈推荐Jimmy Bogard的“ 邪恶领域模型” ( Wicked Domain Models)演示文稿,为您提供一个清晰的例子,说明如何将贫血领域模型转化为有用的模型。 它涉及仔细检查您正在公开的模型以及在业务环境中哪些操作实际上是有效的。

听起来像你会像一个存储库模式。 你可以在这里读到它:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net- MVC应用程序

这个答案可能也有帮助:

ASP.NET MVC的最佳存储库模式