基于ASP.NET Core 6.0的整洁架构

大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。

背景

最近尝试录制了一个系列视频:《ASP.NET Core 6.0+Vue.js 3 实战开发》,本节是视频内部整洁架构的理论和实战的文字稿。因为在录制之前,我通常会编写完整的文字内容作为视频文案,这里分享给大家,希望对你有所帮助。如果您能捧个人场,订阅我的视频,感激不尽。

虽然是收费的视频,但是我的分享不会止步,再次感谢您的阅读。

视频

地址

文章主题

本章将介绍基于ASP.NET Core的整洁架构的设计理念,同时基于理论落地的代码模型,包括文件夹、文件、项目的组织形式以及项目的依赖关系,为企业级可扩展的架构奠定基础。
本章学习的主题包括:

  • 整洁架构介绍
  • 核心层
  • 基础设施层
  • 表示层
  • 测试管理
  • 构建整洁架构解决方案
  • 3.1 整洁架构介绍

    很多公司系统多样,每个系统的分层结构各不相同,这给开发和未来的运维带来了巨大的成本,分层架构看似很简单,但保证整个研发中心都使用统一的分层架构就不容易了。
    那么如何保证整个研发中心都使用统一的分层架构,以达到提高编写代码效率、保证工程统一性的目的?

    我们推荐行业内目前比较流行的整洁架构。

    整洁架构是什么?简而言之,它是组织软件体系结构的原则,可以轻松面对未来的不确定性,方便代码的重构。同时,它可以帮助我们为特定的领域模型构建服务,从而为将来可能的微服务体系结构做好准备。
    我们看下整洁架构的洋葱示意图:

    在整洁架构中,领域层(Domain)和应用层(Application)是架构的核心层。领域层包含实体、枚举和常量设置等,应用层则包含数据传输对象(DTO)、接口、映射、异常、行为和业务逻辑。

    整洁架构和传统三层架构的不同之处在于依赖的不同,因为企业的核心逻辑是可以跨系统共享的,而应用逻辑或业务逻辑是特定的。所以为了复用,现在,我们不再让核心层依赖数据访问和基础设施,而是颠倒这些依赖关系。如上图所示,表示层和基础设施层现在是依赖于我们的核心层,但核心层对任何一层都没有依赖性。

    这种架构必须通过在应用层内添加抽象或接口来实现,这些抽象或接口是在应用层之外的其他层实现的。例如,如果我们想要实现存储库模式(Repository),我们一般会在应用层添加一个IRepository接口,而实现放在基础设施层。

    有了这个设计原则,所有依赖项都指向圆的重心,而最内部的领域层对其他层没有任何依赖性。随后,表示和基础设施层依赖于核心层,而不是彼此依赖。这一点非常重要,因为我们希望确保该系统的逻辑保留在核心内,这样我们就可以重用业务逻辑。我们举个反例,如果表示层依赖基础设施层,那么在发生短信通知的时候,这个逻辑就会停留在表示层中,因为它必须协调表示层和基础设施层之间的交互,如果是这样,未来我们就很难重用这种逻辑。

    如果洋葱示意图不好理解,我们可以结合下面扁平化的示意图来理解。

    扁平示意图:

    我们看到我们的应用层处在最底下,它没有任何依赖项。基础设施层依赖于应用层,最后整个应用程序变得高度可测试,我们可以快速编写单元测试、集成测试和功能测试。
    下面,我们将把每一层的职责逐步展开介绍,最后我们会通过代码(基于.NET 6.0)把整洁架构这套理念落地到我们的解决方案当中。

  • 核心层(Core)将包含应用项目和领域项目;
  • 基础设施层(Infrastructure)将包含数据和共享项目;
  • 展示层(Presentation)将包含一个WebApi项目。
    以上就是基于NET Core解决方案的项目设置和文件夹安排。
  • 3.1.1 核心层(Core)

    核心层是整洁架构的中心,因为它本身不会依赖于其他层。核心层包含两个项目,分别是.Domain和.Application,下面展开描述:
    1)领域层(Domain)项目
    .Domain项目是一个.NET Standard 2.1类库,它包含实体、接口、枚举、DTO等。
    领域项目必须有一个空的项目引用,这表明它对任何项目都没有依赖关系。
    2)应用层(Application)项目
    .Application项目也是一个.NET Standard 2.1类库,它定义了接口,但实现不在这一层。该项目还具有CQRS模式的命令和查询、MediatR的行为、AutoMapper对象映射、异常、模型等。

    思考:
    如果我们要构建微服务,并意识到核心层中有代码会在其他服务中重用,该怎么办?
    答案:
    我们可以抽象出一个共享项目(.Shared),可以作为一个NuGet包,在微服务中共享代码。

    3.1.2 基础设施层

    基础设施层包含应用层中定义的接口的实现,内部还包括SMTP、文件系统或web服务等资源,都在这一层中实现。
    该层是解决方案中的另一个文件夹目录,内部包括多个项目,比如数据层和共享层,另外我们还可以添加Identity的项目进行身份验证(这里暂时省略)。

    1)数据(Data)项目
    数据项目是一个NET 6.0类库项目,用于数据库持久化,内部包括仓储类、实体类、数据迁移等内容。

    2)共享(Shared)项目
    共享项目也是一个NET 6.0类库项目,该项目包含了不同服务之间的共享代码,比如电子邮件、短信或日期等。

    3.1.3 展示层

    展示层是构建web应用程序的地方,我们可以使用ASP.NET Core MVC、ASP.NET Core Web API、单页应用程序(SPA)或移动应用程序。
    1)Web API项目
    本视频会使用一个Web API项目和一个 站作为案例演示。
    WebApi是基于.NET 6.0构建的一个ASP NET Web API项目,可与任何客户端应用程序交互,例如web、移动、桌面和物联 (IoT)。
    此外,WebApi依赖于应用层和基础设施层。
    2)客户端项目
    客户端项目用于用户界面的展示,我们将采用Vue.js 3进行搭建(在第11节介绍),它也将被归类在展示层。

    3.1.4 测试管理

    测试管理项目并不是整洁架构原则的一部分,但是这里也一并介绍。因为,基于测试驱动的开发是一种好的编程习惯,这里的测试包括单元测试、功能测试、集成测试和负载测试等。
    1)单元测试项目
    单元测试是测试代码的小部分代码,比如特定的方法或者服务。可以使用XUnit、NUnit或MSTest项目创建此项目。

    2)集成测试项目
    集成测试是测试类库或组件是否能在一起工作。可以使用XUnit、NUnit或MSTest项目创建此项目。

    现在,我们已经完成整洁架构的整体介绍,是时候编码实现了。

    3.2 构建整洁架构解决方案

    本小节将通过代码落地一个基于整洁架构的物联 解决方案。该项目的目标是适用大部分物联 场景,管理员可以在其中添加、删除、更新和读取物模型。

    本视频的所有命令行都可以在我的博客上获得,不想敲命令的同学可以自行获取。
    开始之前,请先打开终端并导航到项目文件的目录中。

    我这里使用的Hyper终端,对于Windows用户,请使用PowerShell或Git Bash终端。如果使用PowerShell,请记住使用反斜杠而不是正斜杠。

    创建解决方案如果使用IDE(比如Visual Studio 2022)会简单很多,这里使用命令行有个用意,一个是尝鲜,了解命令的构建方式;另一个是考虑将来可能的CI/CD,为自动化开发做准备。
    1)创建解决方案
    我们运行以下命令创建一个iot文件夹:
    mkdir iot
    然后进入该目录:
    cd iot
    使用dotnet CLI创建一个解决方案:
    dotnet new sln
    该命令默认使用目录名称iot作为解决方案的名称。
    接着,在iot目录中创建一个src文件夹:
    mkdir src
    现在,进入src目录,并分别创建三个目录:

    cd srcmkdir 1.coremkdir 2.infrastructuremkdir 3.presentation

    2)创建core文件夹
    一级目录和文件夹创建完成后,我们进入core文件夹:
    cd 1.core
    在core目录中,我们将创建两个项目Iot.Domain和Iot.Application:

    dotnet new classlib -f netstandard2.1 --name Iot.Domaindotnet new classlib -f netstandard2.1 --name Iot.Application

    以上两个项目都是基于.NET Standard 2.1,现在进入Iot.Application目录并创建对Iot.Domain的依赖关系:

    cd Iot.Applicationdotnet add reference ../Iot.Domain/Iot.Domain.csproj

    3)创建infrasturcture文件夹
    接下来,我们转入infrasturcture目录:
    cd ../../2.infrastructure
    在该目录中,我们创建两个基于.NET 6.0的项目,分别是Iot.Data和Iot.Shared:

    dotnet new classlib -f net6.0 --name Iot.Datadotnet new classlib -f net6.0 --name Iot.Shared

    接下来,进入Iot.Data目录:
    cd Iot.Data
    创建对Iot.Domain和Iot.Application的依赖

    dotnet add reference ../../1.core/Iot.Domain/Iot.Domain.csprojdotnet add reference ../../1.core/Iot.Application/Iot.Application.csproj

    现在,转到Iot.Shared目录:
    cd ../Iot.Shared
    创建对Iot.Application的依赖
    dotnet add reference
    ../../1.core/Iot.Application/Iot.Application.csproj

    4)创建presentation文件夹
    转到presentation目录:
    cd ../../3.presentation
    创建WebApi项目,并转入到Iot.WebApi:

    dotnet new webapi --name Iot.WebApicd Iot.WebApi

    创建对Iot.Application和Iot.Data的依赖

    dotnet add reference ../../1.core/Iot.Application/Iot.Application.csprojdotnet add reference ../../2.infrastructure/Iot.Data/Iot.Data.csproj

    接下来,创建对Iot.Shared的依赖:
    dotnet add reference
    ../../2.infrastructure/Iot.Shared/Iot.Shared.csproj

    5)注册项目到解决方案
    转到解决方案所在的根目录:
    cd ../../../
    注册所有的项目到解决方案,注册顺序依次:

    dotnet sln add src/1.core/Iot.Domain/Iot.Domain.csprojdotnet sln add src/1.core/Iot.Application/Iot.Application.csprojdotnet sln add src/2.infrastructure/Iot.Data/Iot.Data.csprojdotnet sln add src/2.infrastructure/Iot.Shared/Iot.Shared.csprojdotnet sln add src/3.presentation/Iot.WebApi/Iot.WebApi.csproj

    至此,我们已经通过.NET CLI完成了我们解决方案的实现,接下来我们关闭终端并使用Visual Studio 2022打开我们的解决方案,如图3-3所示:

    整洁架构的解决方案示意图:

    3.3本节总结

    通过本节的学习,我们了解了什么是整洁架构,整洁架构的模块内容以及依赖关心,以及它将如何帮助开发人员构建可扩展、可演化、可测试的应用程序,比如为将来从单体向微服务演化打下一定的基础。

    另外,我们还学习了如何在整洁架构中构造测试,最后,如何通过dotnet CLI构建ASP.NET Core的解决方案。

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

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2022年7月28日
    下一篇 2022年7月28日

    相关推荐