Skip to content

Latest commit

 

History

History
475 lines (276 loc) · 19.1 KB

File metadata and controls

475 lines (276 loc) · 19.1 KB

四、在 ASP.NET Core 解决方案中应用干净的架构

您还记得前面的章节,在这一章中,您将把干净的体系结构应用到 ASP.NET Core 5 解决方案。 本章教你真实世界中文件、文件夹、项目和 ASP 的组织.NET Core 应用依赖,为你未来的大的和可扩展的 ASP.NET Core 5 企业应用。

组织您的代码、文件和文件夹可以帮助其他开发人员理解您的代码,重构它,并添加未来的特性,这在现实世界的应用中经常发生。

我们将涵盖以下议题:

  • 引入清洁架构
  • 芯层
  • 基础设施层
  • 表示层
  • 管理Tests文件夹
  • 构建一个干净的体系结构解决方案

技术要求

以下是你完成本章所需要的东西:

  • 用于构建后端:Visual Studio 2019, Visual Studio For Mac,或 Rider
  • 搭建一个项目:.NET Core CLI
  • Bash 终端为 Mac 和 Linux 用户
  • Windows 用户使用 PowerShell 或 Git Bash 终端

以下是本章已完成存储库的链接:https://github.com/PacktPublishing/ASP.NET-Core-and-Vue.js/tree/master/Chapter04

介绍干净的架构

那么,洁净建筑到底是什么? 简而言之,干净的架构是一种组织软件架构的原则,可以让开发人员在未来避免对应用进行困难的重构。 清晰的体系结构可以帮助您为特定的领域模型构建服务,从而为微服务体系结构做好准备。

这是一个简洁的 ASP 架构图。 网络应用:

Figure 4.1 – Clean architecture diagram

图 4.1 -清晰的架构图

在干净的建筑中,两个层必须是结构的核心或中心。 这些层就是域层,它包含了您的大多数实体、枚举和设置。 应用层保留了您的数据传输对象(dto)、接口、映射、异常、行为和业务逻辑的大部分。

区别在于,企业逻辑可以在多个系统之间共享,而应用逻辑或业务逻辑是特定的。 现在,我们不再让核心依赖于数据访问和基础设施,而是将这些依赖关系倒置。 因此,表示和基础设施依赖于核心,但核心不依赖于任何一层。 这个结构是通过在应用层中添加抽象或接口来实现的,这些抽象或接口是在应用层之外的其他层中实现的。 例如,如果我们想实现存储库模式,我们将在基础设施应用和实现中添加一个IRepository接口。

按照这个设计原则,所有依赖项都指向中间。 因此,您可以看到,内核与其他层没有依赖关系。 随后,表示和基础设施依赖于核心,而不是相互依赖。 这一点非常重要,因为我们希望确保为该系统创建的逻辑保持在核心中。 例如,如果表示依赖于基础设施来发送一些通知,那么它就是逻辑。 这个逻辑现在必须出现在表示层中。 因此,它必须协调表示和基础设施之间的交互。 通常,我们不希望发生这种情况,因为我们不能重用那个逻辑。 我们想要一个至少能持续十年的系统。

事情是这样的。 如果我们有一个前端 web 应用和一个后端应用,很有可能它在 10 或 15 年内不会存在。 我们需要核心内部的逻辑,在那里它是与所有那些东西隔离的。

如果清晰架构的圆形图(参见图 4.1)有点难以理解,我们可以看看下面的插图:

Figure 4.2 – A flat diagram of clean architecture

图 4.2 -一个干净的架构的平面图

上面的图是简洁架构的简化版本。

此图说明您的应用核心在最底部,它是清晰的架构圆图的中心(参见图 4.1)。

正如你所见,应用核心没有依赖关系。 另一方面,UI 或表示层依赖于应用核心。 您还会注意到,项目基础设施依赖于应用核心。

最后,整个应用变得高度可测试。 您可以快速编写单元测试、集成测试和功能测试。

现在让我们把这些分解成更容易消化的内容。 我们将这些层分为三个文件夹,其中包含。net 项目:

  • core文件夹将有ApplicationDomain项目。
  • infrastructure文件夹将有DataShared项目。
  • presentation文件夹将有WebApi项目。

这是设置项目和安排文件夹的 ASP.NET Core 5 解决方案。

核心层-目录

核心层是干净架构的中心。 我们将把这个实现为 Visual Studio 解决方案中的一个目录或文件夹,这个解决方案可以使用。net Core CLI 创建。 所有其他项目依赖关系都必须指向特定的域和应用项目的核心。 类似地,核心层将永远不依赖于任何其他层。

要设置核心层,我们需要两个项目——DomainApplication项目。

域-项目

这个干净的体系结构部分是一个. net 标准 2.1 类库项目,包含实体、接口、枚举、dto 等等。

Domain项目必须有一个空的项目引用,这表明它不依赖于任何项目。

应用-项目

clean 体系结构的这一部分也是一个. net Standard 2.1 类库项目。 它定义了接口,但实现在这一层之外。 该项目还具有 CQRS 模式的命令和查询、MediatR 的行为、AutoMapper 的概要文件、异常、模型等等。

我们将在本章的构建一个干净的架构解决方案小节中创建上述项目。

如果您刚刚开始构建微服务,并意识到核心层中有代码需要在其他服务或域中重用,该怎么办?

共享内核- NuGet 项目

理想情况下,Shared Kernel项目是一个私有的 NuGet 包,用于在多个项目之间共享代码,例如在微服务中。 这个项目帮助我们轻松地切换我们所依赖的版本,而不会破坏我们的同事或其他团队构建其他解决方案的工作。

现在让我们看一下基础设施层。

基础架构层—目录

基础设施层具有Application项目中定义的接口的类实现。 资源,如 SMTP、文件系统或 web 服务是应用的外部依赖,但在这一层实现。

**这一层是解决方案中保存多个项目的另一个目录。 我们在这里添加的项目是针对数据和共享项目的。 我们也可以添加一个名为Identity for authentication的项目,但是我们将在第 9 章安全 ASP.NET Core,以保持这个干净架构的结构部分最小化。 它们在这里。

要设置基础设施层,我们需要两个项目——DataShared

数据-项目

基础设施层的这一部分是一个用于数据库的。net 5.0 类库项目。 您也可以将此数据项目命名为持久性项目; 持久性和数据是难以处理的。

共享-项目

基础结构层的这个部分也是一个 NET 5.0 类库项目。 该项目将包括不同服务之间的共享代码,如电子邮件、SMS 或日期时间。

同样,您将在本章的构建一个干净的架构解决方案一节中创建基础设施层项目。 同时,让我们进入下一节,即表示层。

表示层-目录

表示层是构建 web 应用的地方。 web 应用可以使用 ASP。 asp.NET Core MVC NET Core Web API,一个单页****应用(SPA),或者一个移动应用。

在本书的各个章节中,我们将构建的实际应用需要一个 Web API 项目和一个网站。

WebApi – project

WebApi是一个 ASP.NET Web API 项目,使用。NET 5.0。 该项目与任何客户端应用交互,如 web、移动、桌面和物联网(物联网)。

此外,WebApi取决于Applicationinfrastructure层。

客户端应用-非项目 web 应用

client-app是作为应用用户界面的 web 应用。 我们将在第十一章的 Todo App中创建 Vue.js 的基础应用,它将在presentational文件夹中。 命名client-app

这就是表示层的内容。 那么,你认为我们应该把应用的测试放在哪里? 让我们看下一节。

管理测试目录

本节不是干净架构原则的一部分,但是最佳实践是使用关注点分离。 因此,根据测试项目所做的测试(如单元测试、功能测试、集成测试和负载测试)来组织测试项目是最佳实践。

我将在下面的小节中列出测试项目,但我们不会在本章中创建它们。 下面是测试项目。

单元测试-项目

一个单元测试项目测试代码的一小部分和特定部分。 可以使用 XUnit、NUnit 或 MSTest 项目创建该项目。

集成测试项目

集成测试项目测试组件是否在一起工作。 可以使用 XUnit、NUnit 或 MSTest 项目创建该项目。

现在我们已经完成了开发人员用 ASP 编写测试的部分.NET Core,是时候为 asp.net 创建层和项目了.NET Core 5 解决方案。

构建一个干净的架构解决方案

在本节中,我们将创建一个解决方案、目录和项目,为应用构建一个干净的体系结构解决方案。 该应用是关于旅行列表和世界各地的地方,管理员可以添加新的,删除,更新和读取旅行目的地列表中的地方。

在我们开始之前,打开你的终端并导航到你的桌面。 确保您的终端或命令行在Desktop目录下。

对于 Windows 用户,使用 PowerShell 或 Git Bash 终端。 Git Bash 终端是您在第 2 章设置开发环境中使用的 Git 版本控制安装程序的一部分。 如果你要使用 PowerShell,记住使用反斜杠而不是正斜杠:

  1. Let's start with the folder of the solution by running the following command:

    mkdir Travel
    

    该命令创建一个名为Travel的文件夹。

  2. The next step is to go inside the Travel folder:

    cd Travel
    

    您的终端现在应该在Travel目录中。

  3. Now, use the dotnet CLI:

    dotnet new sln
    

    该命令创建一个解决方案文件,并从该文件所在的文件夹中获取其名称。

  4. The next step is to create a folder named src:

    mkdir src
    

    src目录在Travel目录中。

  5. Now, navigate to the src directory or folder:

    cd src
    

    src目录中,我们将在这里创建三个文件夹,即三个层:coreinfrastructurepresentation

  6. Now let's create the core folder:

    mkdir core
    

    该命令创建了core目录。

  7. Now create the folder for infrastructure:

    mkdir infrastructure
    

    这个命令创建infrastructure目录或文件夹。

  8. And now, create the presentation directory or folder:

    mkdir presentation
    

    此命令创建presentation目录或文件夹。

  9. Go inside the core directory:

    cd core
    

    core目录中,我们将创建两个项目。 第一个项目将为Domain层:

    dotnet new classlib -f netstandard2.1 --name Travel.Domain
    

    这个命令创建了一个新的. net Standard 2.1 类库Travel.Domain。 第二个项目将为Application层:

    dotnet new classlib -f netstandard2.1 --name Travel.Application
    

    这个命令创建了一个新的. net Standard 2.1 类库Travel.Application

  10. Then, go inside the Travel.Application directory:

```
cd Travel.Application
```

该命令将导航到`Travel.Application`文件夹。
  1. Then we need to add a reference to the Travel.Domain project:
```
dotnet add reference ../Travel.Domain/Travel.Domain.csproj
```

现在,`Travel.Application`项目依赖于`Travel.Domain`项目,但只依赖于这个项目。
  1. Now, navigate to the infrastructure directory:
```
cd ../../infrastructure
```

当位于`infrastructure`目录中时,我们将为`Data`和`Shared`创建项目。
  1. Let's now create the infrastructure for Data or persistence:
```
dotnet new classlib -f net5.0 --name Travel.Data
```

这个命令创建一个新的。net 5.0 类库项目`Travel.Data`。
  1. Let's now create the infrastructure for Shared:
```
dotnet new classlib -f net5.0 --name Travel.Shared
```

这个命令创建另一个名为`Travel.Shared`的。net 5.0 类库项目。
  1. Then, go inside the Travel.Data directory:
```
cd Travel.Data
```

在`Travel.Data`目录中,我们需要使`Travel.Data`依赖于`Domain`和`Application`层。
  1. Let's add a reference to the Travel.Domain project first:
```
dotnet add reference ../../core/Travel.Domain/Travel.Domain.csproj
```

现在,`Travel.Data`依赖于`Travel.Domain`项目。
  1. Now, let's add a reference to the Travel.Application project:
```
dotnet add reference ../../core/Travel.Application/Travel.Application.csproj
```

该命令创建了从`Travel.Data`到`Travel.Application`的依赖项。
  1. Now, go to the Travel.Shared project:
```
cd ../Travel.Shared
```

这个命令将把您带到`Travel.Shared`项目的目录。
  1. Now we can add a reference to the Travel.Application project:
```
dotnet add reference ../../core/Travel.Application/Travel.Application.csproj
```

该命令创建了`Travel.Shared`项目对`Travel.Application`项目的依赖关系。
  1. Now, let's go to the presentation layer:
```
cd ../../presentation
```

现在我们进入了`presentation`层,我们将在这里创建一个 Web API 项目。
  1. We will create the latest ASP.NET Core 5 webapi here:
```
dotnet new webapi --name Travel.WebApi
```

这个命令创建一个名为`Travel.WebApi`的新的 Web API 项目。
  1. Let's navigate inside the Travel.WebApi folder:
```
cd Travel.WebApi
```

现在,在`Travel.WebApi`里面,我们将添加一些参考。
  1. Let's add a reference to the Application layer:
```
dotnet add reference ../../core/Travel.Application/Travel.Application.csproj
```

此命令向`Travel.Application`项目添加一个依赖项。
  1. Now let's add a reference to Data for persistence:
```
dotnet add reference ../../infrastructure/Travel.Data/Travel.Data.csproj
```

此命令向`Travel.Data`项目添加一个依赖项。
  1. The next step is to add a reference to the Shared project:
```
dotnet add reference ../../infrastructure/Travel.Shared/Travel.Shared.csproj
```

这个命令向`Travel.Shared`项目添加了一个依赖项。
  1. Now we can go back to the root folder of the application solution:
```
cd ../../../
```

由于解决方案文件在根文件夹中,我们可以将所有项目注册到解决方案文件中。
  1. The first project we will add to the solution file is the Domain layer:
```
dotnet sln add src/core/Travel.Domain/Travel.Domain.csproj
```

这个命令让解决方案文件知道`Travel.Domain`项目。
  1. We will also add the Application layer of the app:
```
dotnet sln add src/core/Travel.Application/Travel.Application.csproj
```

这个命令让解决方案文件知道`Travel.Application`项目。
  1. The next project to add is Data for persistence:
```
dotnet sln add src/infrastructure/Travel.Data/Travel.Data.csproj
```

这个命令让解决方案文件知道`Travel.Data`项目。
  1. We also have to add the Shared project:
```
dotnet sln add src/infrastructure/Travel.Shared/Travel.Shared.csproj
```

这个命令让解决方案文件知道`Travel.Shared`项目。
  1. Now, the last project to add is the Web API project:
```
dotnet sln add src/presentation/Travel.WebApi/Travel.WebApi.csproj
```

这个命令让解决方案文件知道`Travel.WebApi`项目。

现在,您已经完成了构建 ASP.NET Core 5 应用与一个干净的体系结构。 关闭终端并双击解决方案文件以打开整个应用。

让我们看看 Visual Studio 2019、Visual Studio for Mac 或 Rider 中的应用。

Visual Studio 2019

在 Visual Studio 2019 中,应该是这样的:

Figure 4.3 – Folder structure in Visual Studio 2019

图 4.3 - Visual Studio 2019 中的文件夹结构

Visual Studio 2019 显示Travel作为带有src目录的解决方案。 coreinfrastructurepresentation层必须在src目录下。 您还将看到,ApplicationDomain项目位于core目录下,而DataShared项目位于infrastructure目录下。

类似地,您可以找到 ASP.NET Core 5WebApipresentation目录下。

现在让我们看看 Mac 用户的应用。

Visual Studio for Mac

在 Mac 的 Visual Studio 中,如果你正确地遵循了,它应该是这样的:

Figure 4.4 – Folder structure in Visual Studio for Mac

图 4.4 - Mac Visual Studio 中的文件夹结构

Travel是应用解决方案的名称,其下面是src目录,在干净的体系结构中有core层、infrastructure层和presentation层。

此外,ApplicationDomain项目位于core目录下,而Data项目和Shared项目位于infrastructure目录下。 最后,ASP.NET Core 5WebApi项目必须在presentation目录中。

以上都是针对 Mac 用户的。 结构应该与 Visual Studio 2019 相同。 同样,结构应该与下一节相同,下一节是为 Rider 的用户准备的。 现在让我们看看 Rider IDE 如何显示应用解决方案。

骑手

最后,如果你正在使用 Rider,下面的截图显示了你的应用解决方案的结构:

Figure 4.5 – Folder structure in Rider

图 4.5 - Rider 中的文件夹结构

同样,屏幕截图显示Travel作为解决方案的名称,并且它有src目录,其中包含core层、infrastructure层和presentation层。

ApplicationDomain项目在core目录中,而DataShared项目在infrastructure目录中。

presentation文件夹中,您应该可以看到 ASP.NET CoreWebApi项目

好的,这是一个层次分明、结构清晰的架构解决方案。 下面是完成本章后的源代码的 GitHub 库:

https://github.com/PacktPublishing/ASP.NET-Core-5-and-Vue.js-3/tree/master/Chapter-4/Finish/Travel。

现在让我们总结一下在这里所学到的一切。

总结

通过这些,我们了解了什么是干净的架构,以及它将如何帮助开发人员构建可以持续 10 年甚至更长时间的应用。 我们还了解到,干净的架构使我们的服务可测试,并为微服务做好准备。

我们已经处理了包含干净架构的内容。 核心层与基础设施和表示层没有任何依赖关系。 基础结构层与外部源和表示层(用户使用和交互)进行通信。

您还学习了如何在清晰的体系结构中构建测试,最后,我们学习了如何使用dotnetCLI 来构建一个 ASP.NET Core 解决方案和项目。

现在,通过学习如何将干净的架构应用到 ASP,您已经提高了您的技能.NET Core 5,这将帮助你在未来构建一个高度可伸缩和可测试的应用。

在下一章中,我们将设置数据库并构建路由和控制器,以了解它们如何处理 HTTP 请求。**