带有服务层和存储库层的ASP.NET MVC,应该在哪里定义接口?

时间:2021-08-17 08:04:10

I am in the process of determining a fairly simple layered architecture for a .NET MVC application that has a repository layer and a service layer. I have found some fairly clear and simple examples, notably www.asp.net, and some questions and answers here, but I am looking for something that is a little simpler, suitable for small applications, but that uses different projects, to get the idea across. The example I linked to above has the repository and service as classes in the Models namespace. That just isn't enough of a clear separation for me to be able to illustrate it properly.

我正在为具有存储库层和服务层的.NET MVC应用程序确定一个相当简单的分层体系结构。我找到了一些相当清晰和简单的例子,特别是www.asp.net,以及这里的一些问题和答案,但我正在寻找一些更简单的东西,适合小型应用程序,但它使用不同的项目,以获得跨越的想法。我上面链接的示例将存储库和服务作为Models命名空间中的类。这对我来说是不够明确的分离能够恰当地说明它。

I have a separate project for the repository that implements interface IRepository. There is a separarate project for the Service that implements IService and takes an IRepository (constructor injection). The Service implements IService. It is enough for this example that the controller instantiate the service, no need for an IoC container just yet. Think of it as an intermediate step to understanding best architectural practices, part of a sequence that builds progressively to include dependency injection and possibly more layers.

我有一个单独的项目用于实现接口IRepository的存储库。服务实现IService并采用IRepository(构造函数注入)有一个单独的项目。该服务实现了IService。这个例子就足以让控制器实例化服务,而不需要IoC容器。将其视为理解最佳架构实践的中间步骤,这是逐步构建以包含依赖注入和可能更多层的序列的一部分。

The question is, where should I define IRepository and IService? Both the service and repository projects need to reference them, of course. It seems clear then that they should be defined in another project referenced by both the service and repository projects. If so, what would a good naming convention be? Something like XXXXContracts?

问题是,我应该在哪里定义IRepository和IService?当然,服务和存储库项目都需要引用它们。很明显,它们应该在服务和存储库项目引用的另一个项目中定义。如果是这样,那么一个好的命名约定是什么?有什么像XXXXContracts?

Likewise, for the data models passed between the presentation, service and repository layers, is it acceptable to have a separate project called XXXXModels referenced by all the layers? I understand that in some cases the models passed between the service and repository layer can differ from those passed between the service layer and the presentation layer, but the principle is the same.

同样,对于在表示层,服务层和存储库层之间传递的数据模型,是否可以使用所有层引用的名为XXXXModels的单独项目?我理解在某些情况下,服务和存储库层之间传递的模型可能与服务层和表示层之间传递的模型不同,但原理是相同的。

I have found answers to similar questions here, but they tend to involve a more complicated architecture than what I have outlined here. I'm looking to achieve a really simple and clean illustration of the two layers that can be seen as a step or two above referencing the data layer and having business logic in the controllers, that's all. I know there is a strong and valid argument for going straight to the full-blown best practice, but not everyone is suited to making that jump in one go.

我在这里找到了类似问题的答案,但它们往往涉及比我在此概述的更复杂的架构。我希望实现一个非常简单和干净的两层图解,可以看作是参考数据层并在控制器中具有业务逻辑的一两步,就是这样。我知道有一个强有力的论据可以直接进入全面的最佳实践,但不是每个人都适合一次性完成跳跃。

1 个解决方案

#1


53  

Introduction

This is something I've asked myself as well. One burning question I always have is similar to yours;

这也是我自己也问过的。我一直有的一个问题与你的问题类似;

what would a good naming convention be?

一个好的命名惯例是什么?

How should I name things? Should they go in folders or projects?

我应该如何命名?他们应该进入文件夹或项目吗?

After searching around I suspect the answer is that it doesn't really matter. What's important is that you solution has some sensible architecture and that you try to follow good practices such as SOLID.

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

My ASP.NET MVC heroes on this topic are Jeffrey Palermo, Steve Smith and Jimmy Bogard.

我关于这个主题的ASP.NET MVC英雄是Jeffrey Palermo,Steve Smith和Jimmy Bogard。

Onion Architecture

Jeffrey Palermo discusses a combination of old ideas but brings them together and gives it the visually stimulating name of Onion Architecture (a recommended read). Jeffrey shows a good approach to the problem of where to put things. He explains that at the centre (or top) of your application you have your Core. This layer is where you should put interfaces such as IRepository and IService.

杰弗里·巴勒莫(Jeffrey Palermo)讨论了旧观念的组合,但将它们结合在一起,并赋予其洋葱建筑的视觉刺激名称(推荐阅读)。杰弗里展示了一个解决问题的好方法。他解释说,在你的应用程序的中心(或顶部)你有你的核心。您可以在此层放置IRepository和IService等接口。

Almost all of your interfaces should go in the core and everything else (other projects) can all reference the core. This way everything knows the skeletal structure of the application without knowing the implementation details.

几乎所有的接口都应该进入核心,其他所有(其他项目)都可以引用核心。这样一切都知道应用程序的骨架结构,而不知道实现细节。

带有服务层和存储库层的ASP.NET MVC,应该在哪里定义接口?

Try to have your UI layer reference as little as possible (within reason). In one of my applications my UI (MVC) layer only references the Core. Everything it needs is injected into it with Dependency Injection.

尝试尽可能少地(在合理范围内)引用您的UI图层。在我的一个应用程序中,我的UI(MVC)层仅引用Core。它所需要的一切都通过依赖注入注入其中。

Steve Smith discusses Onion Architecture and similar ideas with demonstrations in MVC Solution Best Practices: A solution to the solution problem

史蒂夫史密斯通过MVC解决方案最佳实践中的演示讨论了洋葱架构和类似的想法:解决方案问题的解决方案

My solution

In my MVC solutions I have a typical structure like this:

在我的MVC解决方案中,我有一个典型的结构,如下所示:

  • MyProject.Core
  • MyProject.Core
  • MyProject.Domain
  • MyProject.Domain
  • MyProject.DependencyInjection
  • MyProject.DependencyInjection
  • MyProject.Infrastructure
  • MyProject.Infrastructure
  • MyProject.Web
  • MyProject.Web
  • MyProject.Tests
  • MyProject.Tests

The Core contains my interfaces. It is usually divided up into folders like Services, Models, Domain, Repositories and so on.

核心包含我的接口。它通常分为服务,模型,域,存储库等文件夹。

The Domain layer references only the core and contains my implementation. It provides a lot of the concrete classes for the domain abstraction in the core. It deals with a lot of business logic, processing, command handling, manager classes, concrete service implementations and so on. I consider it a fairly inner-layer and so it references as little as possible.

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

The DependencyInjection layer contains my chosen DI package/framework and implementation details. I consider it an outer layer; similar to UI or Infrastructure and so it's ok if it references a lot. It's not necessary for this layer to be a separate project and many people will tell you not to do this. That's ok; do what works for the complexity of your project. I like my DI to be its own thing. The good thing about it being so separate is that I could replace the DI framework with a different one and things would be fine. No layers reference the DI project.

DependencyInjection层包含我选择的DI包/框架和实现细节。我认为它是一个外层;类似于UI或基础设施,所以如果它引用很多就没关系。这一层没有必要成为一个单独的项目,许多人会告诉你不要这样做。没关系;做什么适用于您的项目的复杂性。我喜欢我的DI是自己的东西。关于它如此独立的好处是我可以用不同的方式替换DI框架,事情就好了。没有图层参考DI项目。

The Infrastructure layer contains information about logging, emailing and data access. It will contain my ORM of choice. It's not business-logic stuff and it's not UI stuff. It's the railroad of my solution to get things done. It's on the outer layer but it only references the Core.

Infrastructure层包含有关日志记录,电子邮件和数据访问的信息。它将包含我选择的ORM。这不是商业逻辑的东西,也不是UI的东西。这是我完成任务的解决方案的铁路。它在外层,但它只引用Core。

The Web layer is my MVC project and only references the Core.

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

Complexity and final thoughts

I have found answers to similar questions here, but they tend to involve a more complicated architecture than what I have outlined here

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

It's a good point. It's important to keep in mind the complexity of your problem. But don't be deterred by good solution practices. My solution and Onion Architecture are not necessarily very complex and don't really bloat your solution. They just keep things separate.

这是一个好点。记住问题的复杂性非常重要。但不要被良好的解决方案做法所吓倒。我的解决方案和洋葱架构不一定非常复杂,并没有真正膨胀你的解决方案。他们只是把事情分开。

In Evolutionary Project Structure, Jimmy Bogard talks about things being over-complex. If what I've said seems too complex, follow Jimmy's advice and put it all in the one project (your UI layer). That's ok - as long as it suits you.

在进化项目结构中,吉米博加德谈论的事情过于复杂。如果我所说的看起来太复杂,请遵循Jimmy的建议并将其全部放在一个项目(您的UI层)中。没关系 - 只要它适合你。

Remember to take my solution only as an idea - something to consider; my approach is an attempt to follow sage advice from the best, but I'm sure I've only succeeded so much; I can (and must) still improve.

记住只把我的解决方案作为一个想法 - 需要考虑的事情;我的方法是尝试从最好的方面遵循圣人的建议,但我相信我只是取得了如此多的成功;我可以(而且必须)仍在改进。

#1


53  

Introduction

This is something I've asked myself as well. One burning question I always have is similar to yours;

这也是我自己也问过的。我一直有的一个问题与你的问题类似;

what would a good naming convention be?

一个好的命名惯例是什么?

How should I name things? Should they go in folders or projects?

我应该如何命名?他们应该进入文件夹或项目吗?

After searching around I suspect the answer is that it doesn't really matter. What's important is that you solution has some sensible architecture and that you try to follow good practices such as SOLID.

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

My ASP.NET MVC heroes on this topic are Jeffrey Palermo, Steve Smith and Jimmy Bogard.

我关于这个主题的ASP.NET MVC英雄是Jeffrey Palermo,Steve Smith和Jimmy Bogard。

Onion Architecture

Jeffrey Palermo discusses a combination of old ideas but brings them together and gives it the visually stimulating name of Onion Architecture (a recommended read). Jeffrey shows a good approach to the problem of where to put things. He explains that at the centre (or top) of your application you have your Core. This layer is where you should put interfaces such as IRepository and IService.

杰弗里·巴勒莫(Jeffrey Palermo)讨论了旧观念的组合,但将它们结合在一起,并赋予其洋葱建筑的视觉刺激名称(推荐阅读)。杰弗里展示了一个解决问题的好方法。他解释说,在你的应用程序的中心(或顶部)你有你的核心。您可以在此层放置IRepository和IService等接口。

Almost all of your interfaces should go in the core and everything else (other projects) can all reference the core. This way everything knows the skeletal structure of the application without knowing the implementation details.

几乎所有的接口都应该进入核心,其他所有(其他项目)都可以引用核心。这样一切都知道应用程序的骨架结构,而不知道实现细节。

带有服务层和存储库层的ASP.NET MVC,应该在哪里定义接口?

Try to have your UI layer reference as little as possible (within reason). In one of my applications my UI (MVC) layer only references the Core. Everything it needs is injected into it with Dependency Injection.

尝试尽可能少地(在合理范围内)引用您的UI图层。在我的一个应用程序中,我的UI(MVC)层仅引用Core。它所需要的一切都通过依赖注入注入其中。

Steve Smith discusses Onion Architecture and similar ideas with demonstrations in MVC Solution Best Practices: A solution to the solution problem

史蒂夫史密斯通过MVC解决方案最佳实践中的演示讨论了洋葱架构和类似的想法:解决方案问题的解决方案

My solution

In my MVC solutions I have a typical structure like this:

在我的MVC解决方案中,我有一个典型的结构,如下所示:

  • MyProject.Core
  • MyProject.Core
  • MyProject.Domain
  • MyProject.Domain
  • MyProject.DependencyInjection
  • MyProject.DependencyInjection
  • MyProject.Infrastructure
  • MyProject.Infrastructure
  • MyProject.Web
  • MyProject.Web
  • MyProject.Tests
  • MyProject.Tests

The Core contains my interfaces. It is usually divided up into folders like Services, Models, Domain, Repositories and so on.

核心包含我的接口。它通常分为服务,模型,域,存储库等文件夹。

The Domain layer references only the core and contains my implementation. It provides a lot of the concrete classes for the domain abstraction in the core. It deals with a lot of business logic, processing, command handling, manager classes, concrete service implementations and so on. I consider it a fairly inner-layer and so it references as little as possible.

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

The DependencyInjection layer contains my chosen DI package/framework and implementation details. I consider it an outer layer; similar to UI or Infrastructure and so it's ok if it references a lot. It's not necessary for this layer to be a separate project and many people will tell you not to do this. That's ok; do what works for the complexity of your project. I like my DI to be its own thing. The good thing about it being so separate is that I could replace the DI framework with a different one and things would be fine. No layers reference the DI project.

DependencyInjection层包含我选择的DI包/框架和实现细节。我认为它是一个外层;类似于UI或基础设施,所以如果它引用很多就没关系。这一层没有必要成为一个单独的项目,许多人会告诉你不要这样做。没关系;做什么适用于您的项目的复杂性。我喜欢我的DI是自己的东西。关于它如此独立的好处是我可以用不同的方式替换DI框架,事情就好了。没有图层参考DI项目。

The Infrastructure layer contains information about logging, emailing and data access. It will contain my ORM of choice. It's not business-logic stuff and it's not UI stuff. It's the railroad of my solution to get things done. It's on the outer layer but it only references the Core.

Infrastructure层包含有关日志记录,电子邮件和数据访问的信息。它将包含我选择的ORM。这不是商业逻辑的东西,也不是UI的东西。这是我完成任务的解决方案的铁路。它在外层,但它只引用Core。

The Web layer is my MVC project and only references the Core.

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

Complexity and final thoughts

I have found answers to similar questions here, but they tend to involve a more complicated architecture than what I have outlined here

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

It's a good point. It's important to keep in mind the complexity of your problem. But don't be deterred by good solution practices. My solution and Onion Architecture are not necessarily very complex and don't really bloat your solution. They just keep things separate.

这是一个好点。记住问题的复杂性非常重要。但不要被良好的解决方案做法所吓倒。我的解决方案和洋葱架构不一定非常复杂,并没有真正膨胀你的解决方案。他们只是把事情分开。

In Evolutionary Project Structure, Jimmy Bogard talks about things being over-complex. If what I've said seems too complex, follow Jimmy's advice and put it all in the one project (your UI layer). That's ok - as long as it suits you.

在进化项目结构中,吉米博加德谈论的事情过于复杂。如果我所说的看起来太复杂,请遵循Jimmy的建议并将其全部放在一个项目(您的UI层)中。没关系 - 只要它适合你。

Remember to take my solution only as an idea - something to consider; my approach is an attempt to follow sage advice from the best, but I'm sure I've only succeeded so much; I can (and must) still improve.

记住只把我的解决方案作为一个想法 - 需要考虑的事情;我的方法是尝试从最好的方面遵循圣人的建议,但我相信我只是取得了如此多的成功;我可以(而且必须)仍在改进。