具有服务层和存储库层的 ASP.NET MVC,应该在哪里定义接口?
Posted
技术标签:
【中文标题】具有服务层和存储库层的 ASP.NET MVC,应该在哪里定义接口?【英文标题】:ASP.NET MVC with service layer and repository layer, where should the interfaces be defined? 【发布时间】:2013-11-18 10:13:33 【问题描述】:我正在为具有存储库层和服务层的 .NET MVC 应用程序确定一个相当简单的分层架构。我找到了一些相当清晰和简单的示例,特别是www.asp.net,以及一些问题和答案,但我正在寻找更简单的东西,适用于小型应用程序,但使用不同的项目,以传达这个想法.我上面链接的示例将存储库和服务作为模型命名空间中的类。这还不足以让我能够正确地说明它。
我有一个单独的项目用于实现接口 IRepository 的存储库。 Service 有一个单独的项目,它实现 IService 并采用 IRepository(构造函数注入)。服务实现 IService。对于这个例子来说,控制器实例化服务就足够了,现在还不需要 IoC 容器。将其视为理解最佳架构实践的中间步骤,是逐步构建以包括依赖注入和可能更多层的序列的一部分。
问题是,我应该在哪里定义 IRepository 和 IService?当然,服务和存储库项目都需要引用它们。很明显,它们应该在服务和存储库项目引用的另一个项目中定义。如果是这样,一个好的命名约定是什么?像 XXXXContracts 这样的东西?
同样,对于在表示层、服务层和存储库层之间传递的数据模型,是否可以接受所有层都引用一个名为 XXXXModels 的单独项目?我知道在某些情况下,服务层和存储层之间传递的模型可能与服务层和表示层之间传递的模型不同,但原理是一样的。
我在这里找到了类似问题的答案,但它们往往涉及比我在这里概述的更复杂的架构。我希望实现两个层的真正简单和清晰的说明,这可以看作是引用数据层并在控制器中具有业务逻辑的一两个步骤,仅此而已。我知道直接采用全面的最佳实践有一个强有力且有效的论据,但并不是每个人都适合一次性实现这一目标。
【问题讨论】:
【参考方案1】:简介
这也是我问自己的问题。我一直有一个迫切的问题与您的问题相似;
好的命名约定是什么?
我应该如何命名事物?它们应该放在文件夹还是项目中?
四处搜索后,我怀疑答案是这并不重要。重要的是您的解决方案具有一些合理的架构,并且您尝试遵循 SOLID 等良好实践。
我在这个主题上的 ASP.NET MVC 英雄是 Jeffrey Palermo、Steve Smith 和 Jimmy Bogard。
洋葱架构
Jeffrey Palermo 讨论了旧想法的组合,但将它们结合在一起,并赋予其视觉刺激的名称 Onion Architecture(推荐阅读)。杰弗里展示了一个很好的方法来解决把东西放在哪里的问题。他解释说,在您的应用程序的中心(或顶部),您有您的Core。这一层是你应该放置接口的地方,比如IRepository
和IService
。
几乎所有接口都应该放在核心中,其他所有内容(其他项目)都可以引用核心。这样一来,一切都知道应用程序的骨架结构,而无需知道实现细节。
尝试尽可能少地引用您的 UI 层(在合理范围内)。在我的一个应用程序中,我的 UI (MVC) 层仅引用了 Core。它需要的一切都通过Dependency Injection 注入其中。
Steve Smith 在MVC Solution Best Practices: A solution to the solution problem 中通过演示讨论了洋葱架构和类似想法
我的解决方案
在我的 MVC 解决方案中,我有一个这样的典型结构:
MyProject.Core MyProject.Domain MyProject.DependencyInjection MyProject.Infrastructure MyProject.Web MyProject.TestsCore 包含我的界面。它通常分为服务、模型、域、存储库等文件夹。
Domain 层仅引用核心并包含我的实现。它为核心中的领域抽象提供了很多具体的类。它处理大量的业务逻辑、处理、命令处理、管理器类、具体的服务实现等等。我认为它是一个相当内层,因此它尽可能少地引用。
DependencyInjection 层包含我选择的 DI 包/框架和实现细节。我认为它是外层;类似于 UI 或 Infrastructure,所以如果它引用很多也没关系。这一层没有必要成为一个单独的项目,很多人会告诉你不要这样做。没关系;做适合您项目复杂性的事情。我喜欢我的 DI 是它自己的东西。它如此独立的好处是我可以用不同的框架替换 DI 框架,一切都会好起来的。没有图层引用 DI 项目。
基础设施层包含有关日志记录、电子邮件和数据访问的信息。它将包含我选择的ORM。这不是业务逻辑的东西,也不是 UI 的东西。这是我完成工作的解决方案的铁路。它在外层,但它只引用核心。
Web 层是我的 MVC 项目,仅引用 Core。
复杂性和最终想法
我在这里找到了类似问题的答案,但它们往往涉及比我在这里概述的更复杂的架构
这是一个很好的观点。记住问题的复杂性很重要。但不要被良好的解决方案所吓倒。我的解决方案和 Onion Architecture 不一定非常复杂,也不会真正使您的解决方案膨胀。他们只是把事情分开。
在Evolutionary Project Structure 中,Jimmy Bogard 谈到事情过于复杂。如果我所说的似乎太复杂,请按照 Jimmy 的建议,将它们全部放在一个项目(您的 UI 层)中。没关系 - 只要它适合你。
请记住仅将我的解决方案作为一个想法 - 需要考虑的事情;我的方法是尝试遵循最好的明智建议,但我确信我只成功了这么多;我可以(而且必须)继续改进。
【讨论】:
+1 表示洋葱。示例:ludwigstuyck.wordpress.com/2013/03/05/… 不错的答案。如果 Web 层仅引用核心,您如何登录控制器?其他跨项目的助手呢?你把它们放在哪里? 我很惊讶这个答案没有更多的赞成票。写得很好,很有趣! 很好的答案,正是我想要创建一个新的 Web 应用程序。 @systempuntoout 尝试研究 AOP 和拦截概念。它将为您提供有关横切关注点的想法。以上是关于具有服务层和存储库层的 ASP.NET MVC,应该在哪里定义接口?的主要内容,如果未能解决你的问题,请参考以下文章
MVC3 应用程序/服务层/存储库层/POCO 类/EF4 - 问题!
asp.net mvc怎么按时间段查询 下面这段代码是查询代码 如何在C层和V层实现