ASP.NET MVC中的服务层和仓储层,接口应该定义在哪里?

18
我正在确定一个相当简单的分层架构,用于拥有存储库层和服务层的 .NET MVC 应用程序。我找到了一些相当清晰简单的示例,尤其是在 www.asp.net 和这里的一些问题和答案中,但我正在寻找一些稍微简单的东西,适用于小型应用程序,但使用不同的项目来传达理念。我上面链接的示例将存储库和服务作为 Models 命名空间中的类。这对我来说不够清晰地分离,无法恰当地说明它。
我为实现 IRepository 接口的存储库单独建立了一个项目。服务层也有一个单独的项目,实现 IService 接口并使用 IRepository(构造函数注入)。服务层实现了 IService。对于此示例,仅需要控制器实例化服务,暂时不需要 IoC 容器。把它看作是理解最佳架构实践的中间步骤,这是一个渐进式的序列,包括依赖注入和可能更多的层。
问题是,我应该在哪里定义 IRepository 和 IService?当然,服务和存储库项目都需要引用它们。因此,它们应该在另一个由服务和存储库项目引用的项目中定义。如果是这样,良好的命名约定将是什么?类似于 XXXXContracts?
同样地,传递给表示层、服务层和存储库层之间的数据模型,是否可以有一个名为 XXXXModels 的单独项目被所有层引用?我了解到,某些情况下,在服务和存储库层之间传递的模型可能与在服务层和表示层之间传递的模型不同,但原则相同。
我在这里找到了类似问题的答案,但它们往往涉及比我在这里概述的更复杂的架构。我正在寻求实现两层的真正简单而干净的说明,可以看作是在引用数据层并将业务逻辑放在控制器中之上的一步或两步,仅此而已。我知道有一个强有力且有效的理由可以直接跳转到完全成熟的最佳实践,但并非每个人都适合一步到位。
1个回答

56

介绍

我也曾经问过自己这个问题。我总是有一个类似于你的问题:

好的命名规范应该是什么样的?

我应该如何命名东西?它们应该放在文件夹或项目中吗?

在搜索后,我怀疑答案是 并不重要。重要的是你的解决方案具有一些合理的架构,并且你尝试遵循良好的实践,例如SOLID

在这个主题上,我的ASP.NET MVC英雄是Jeffrey Palermo, Steve SmithJimmy Bogard

洋葱架构

Jeffrey Palermo讨论了一些旧思想的组合,并将其合并在一起,并给它起了一个视觉上令人兴奋的名字Onion Architecture(建议阅读)。 Jeffrey展示了解决问题的好方法,即将东西放在哪里。他解释说,在应用程序的中心(或顶部),您有Core。这个层是您应该放置接口(如IRepositoryIService)的地方。
几乎所有的接口都应该放在核心中,其他所有项目都可以引用核心。通过这种方式,所有内容都知道应用程序的骨架结构,而不知道实现细节。

Onion Architecture overview

尽量减少UI层的引用(在合理范围内)。在我的一个应用程序中,我的UI(MVC)层仅引用Core。它需要的所有内容都是通过依赖注入注入其中的。
Steve Smith在MVC解决方案最佳实践:解决问题的解决方案中演示了洋葱架构和类似思想。

我的解决方案

在我的MVC解决方案中,我有一个典型的结构,如下所示:
  • MyProject.Core
  • MyProject.Domain
  • MyProject.DependencyInjection
  • MyProject.Infrastructure
  • MyProject.Web
  • MyProject.Tests

核心包含我的接口。通常会分成像服务、模型、域、存储库等文件夹。

层仅引用核心,并包含我的实现。它为核心中的域抽象提供了许多具体类。它处理大量的业务逻辑、处理、命令处理、管理器类、具体服务实现等。我认为它是一个相当内部的层,因此尽可能少引用。

依赖注入层包含我选择的DI包/框架和实现细节。我认为它是一个外层;类似于UI或基础设施,因此它可以引用很多内容。这个层不需要是一个单独的项目,很多人会告诉你不要这样做。那没关系;按照你的项目复杂度来做。我喜欢我的DI成为一个独立的东西。它如此独立的好处是我可以用不同的DI框架替换它,一切都会很好。没有层引用DI项目。

基础设施层包含有关日志记录、电子邮件和数据访问的信息。它将包含我选择的ORM。它不是业务逻辑内容,也不是UI内容。它是我的解决方案中实现任务的铁路。它在外层,但只引用核心。

Web层是我的MVC项目,仅引用核心。

复杂性和最终思考

我在这里找到了类似问题的答案,但它们往往涉及比我所概述的更复杂的架构

这是一个好观点。重要的是要记住您的问题的复杂性。但不要被良好的解决方案做法所吓倒。我的解决方案和洋葱架构并不一定非常复杂,也不会使您的解决方案变得臃肿。它们只是保持事物分开。

进化式项目结构中,Jimmy Bogard谈到了过度复杂的问题。如果我所说的内容似乎太复杂,请遵循Jimmy的建议,并将所有内容放入一个项目中(即您的UI层)。只要适合你就可以了。
请记住,我的解决方案仅作为一个想法-需要考虑的东西;我的方法是尝试遵循最佳建议的努力,但我肯定只取得了一部分成功;我仍然可以(并且必须)改进。

2
+1 对洋葱。示例:http://ludwigstuyck.wordpress.com/2013/03/05/a-reference-architecture-part-1/ - L-Four
不错的回答。如果Web层仅引用核心,您如何登录控制器?其他跨项目的帮助程序怎么办?您将它们放在哪里? - systempuntoout
1
我很惊讶这个答案没有更多的赞。写得非常好,很有趣! - sebbzzz
很好的答案,正是我想要创建新Web应用程序所需要的。 - Shane van Wyk
@systempuntoout,建议您研究AOP和拦截概念。这将为您提供有关交叉关注点的想法。 - Ant Radha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接