在上一章中,我们构建了一个简单的全栈 Web 应用程序,我们已经看到了使用 ABP 框架开发应用的典型流程,在接下来,我们将使用 ABP 框架创建更高级的应用程序。

给出具有现实世界复杂性的例子并不容易,考虑到这一点,我们准备了一个使用 ABP 框架构建的完整的、真实的参考应用程序:EventHub。它是开源的,可在 GitHub 上免费获得。

EventHub 解决方案可在openeventhub.com上实时浏览。您可以尝试一下来探索它。我们已经建立了持续集成/持续开发(CI/CD) 管道,会实时进行网站更新,因为我们正在开发它并获得社区的贡献。欢迎随意查看其源代码,提交错误报告或功能请求!顾名思义,这是一个开放的平台。

在本文中,我们将在以下部分中研究 EventHub 解决方案:

  • 应用介绍
  • 架构探索
  • 方案运行

一、应用介绍

活动中心是一个平台,用于组织创建活动。您可以亲自在线创建活动。以下截图取自openeventhub.com网站的主页
探索ABP的EventHub解决方案-LMLPHP

您可以浏览主页上即将举行的 活动部分。单击一个事件了解详细信息并注册该事件。在活动开始之前或活动时间更改之时,您会收到电子邮件通知。

这是创建新事件页面的另一个截图:
探索ABP的EventHub解决方案-LMLPHP

您可以在此页面上选择您拥有的组织,设置标题、时间和描述,选择封面图片,并确定有关您正在组织活动的其他详细信息。

如果您想了解更多信息,请在openeventhub.com注册并探索该平台。在本书中,我想讨论的是技术细节而不是业务功能。让我们从大局开始,了解整个方案的架构。

二、架构探索

整体架构图

下面是解决方案整体架构图:
探索ABP的EventHub解决方案-LMLPHP

如图所示,有六个应用程序和一个数据库,下面提供了更多的信息:

  • 身份验证服务器:此服务用于登录、注册和管理用户帐户。它基于 ABP 的标准Account模块,该模块基于该IdentityServer库。它是单点登录(SSO) 服务,这意味着如果您登录/退出到其中一个应用程序,那么您将登录/退出到所有应用程序。那是一个ASP.NET Core Razor Pages应用程序,它直接连接到数据库
  • 主站:这是最终用户用来注册和创建活动的平台 (www.openeventhub.com)它是一个使用Main HTTP API作为后端的Razor Pages应用程序
  • 管理员后台:此应用允许管理员管理组织、事件和系统。它使用Admin HTTP API进行所有操作,这是一个Blazor WebAssembly应用。
  • 主站 HTTP API:主网使用调用的 HTTP API接口。
  • Admin HTTP API:管理员后台调用的 HTTP API。
  • 后台服务:运行系统后台进程服务和后台作业的控制台程序。
  • 数据库:这是一个关系型 PostgreSQL数据库,用于存储系统中的所有数据。
    由于是分布式系统,所以使用Redis作为分布式缓存服务器。

我们先从身份验证流程开始。

认证流程

如前所述,Authentication Server是一个 SSO 服务,用于对用户和客户端进行身份验证。当用户想要登录时,主网站管理员后台使用OpenID Connect(OIDC) 协议将用户重定向到**身份验证服务器。**下图显示了登录过程:
探索ABP的EventHub解决方案-LMLPHP

它的逻辑顺序是这样的:

  • 当用户想要访问主站时 (1),主站将用户重定向到身份验证服务 (2)
  • 身份验证服务有一个登录页面,用户可以输入用户名和密码或注册为新用户。登录完成后,用户将重定向回主站,并返回授权码 (3)(4)
  • 然后,主站使用获得的授权码向服务器执行令牌请求 (5)
  • 身份验证服务返回一个标识符(包含一些用户信息,例如用户名、ID、电子邮件等)和一个访问令牌 (6)
  • 主站将访问令牌存储在 cookie 中(管理员后台将令牌存储在浏览器的本地存储中),以便在下一个请求中获取。在接下来的请求中,它从 cookie 中获取访问令牌并将其添加到 HTTP 请求头中,同时对Main HTTP API执行 HTTP 请求 (7)
  • Main HTTP API 验证访问令牌 (8) 并授权请求。

所有这些过程都由 ABP的AccountIdentityServer模块完成。

探索解决方案

EventHub.NET 解决方案由多个项目组成,按应用类型分组,如下图所示:
探索ABP的EventHub解决方案-LMLPHP

该解决方案有两个应用层和一个领域层,以及相应的 HTTP API 和用户界面(UI) 层。两个应用层共享领域层,但它们具有不同的应用程序逻辑,因此它们是分开的。

common 文件夹

我们先介绍common文件夹。该文件夹包含通用库和服务,如下所述:

  • EventHub.Domain项目是包含实体、领域服务和其他领域对象的领域层。EventHub.Domain.Shared项目包含常量和一些其他类,它们是所有层和应用的共享层。
  • EventHub.EntityFrameworkCore项目包含DbContext、映射、数据库迁移、存储库实现以及与 EF Core 相关的其他代码。
  • EventHub.DbMigrator项目是一个控制台应用,用于数据库迁移并初始化数据(例如管理员用户/角色及其权限),支持开发和生产环境。
  • EventHub.BackgroundServices项目是另一个控制台应用,用于运行后台作业。

www 文件夹

www文件夹包含主站项目:

  • EventHub.Application包括应用服务的实现,EventHub.Application.Contracts包括应用服务接口和DTO。
  • EventHub.HttpApi包含 UI(Web)层使用的 API 控制器,该控制器是应用服务的简单包装器。
  • EventHub.HttpApi.Host托管 HTTP API 层。通过这种方式,托管逻辑与包含 API 控制器的项目分离(重用EventHub.HttpApi)。
  • EventHub.HttpApi.Client一个调用 API 的客户端。UI (web) 层使用该项目来调用 HTTP API。该项目使用 ABP 的动态 C# 代理功能。
  • EventHub.Web是应用程序的 UI 层。这是一个典型的 Razor Pages 应用。它没有数据库连接,调用Main HTTP API进行操作。
  • EventHub.Web.Theme自定义主题。ABP 有一个主题系统,您可以使用它来构建自己的主题并在其他应用中重用它们。EventHub.Web项目使用此主题。主题系统将在第 4 部分用户界面和 API 开发中介绍。

admin 文件夹

admin文件夹包含管理员后台,由维护系统的用户使用,这里有更详细的解释:

  • EventHub.Admin.Application项目是管理员后台的应用层,包含应用服务的实现,EventHub.Admin.Application.Contracts包含与UI层共享的应用服务接口和DTO。
  • EventHub.Admin.HttpApi包含 UI(Web)层使用的 API 控制器。
  • EventHub.Admin.HttpApi.Host项目托管 HTTP API 层。通过这种方式,托管逻辑与包含 API 控制器的项目分离。
  • EventHub.Admin.HttpApi.Client项目是一个调用 API 的客户端。UI (web) 层使用该项目来调用 HTTP API。该项目使用 ABP 的动态 C# 代理功能。
  • EventHub.Admin.Web项目是应用程序的 UI 层。这是一个在浏览器中运行并对服务器执行 HTTP API 调用的Blazor WebAssembly应用。

account 文件夹

account文件夹包含单个项目EventHub.IdentityServer,其他应用程序使用该项目对用户进行身份验证。

我们已经简要地介绍了解决方案中的所有项目,下面介绍项目之间的依赖关系。

项目依赖关系

在接下来的部分中,我将展示每个项目的依赖关系图,以便您了解代码库的组织方式。我们从基本应用程序主站开始。

Main Application(主站)

请记住,主站是互联网终端用户使用应用程序:www.openeventhub.com。下图显示了项目依赖关系,从应用程序的根项目Web开始:
探索ABP的EventHub解决方案-LMLPHP

Web项目依赖于Web.Theme,它实现了 EventHub 的 UI 主题。Web.Theme是一个单独的项目,因为它同时被Authentication Server复用。

项目Web也依赖于HttpApi项目。我们可以在Web项目的客户端 (JavaScript) 中调用这些 API,当您通过HttpApi.Client调用 HTTP API 时,请求将重定向到 Main HTTP API (后端)。

HttpApi引用.Contracts接口层,而HttpApi.Client使用 ABP 的动态 C# 代理实现了这些接口,并通过执行HTTP远程调用Main HTTP API

Main HTTP API(主站API)

主站使用Main HTTP API作为后端 API。它包含应用领域逻辑。下图显示了根项目HttpApi.Host及其直接或间接依赖项:
探索ABP的EventHub解决方案-LMLPHP

  • 通过引用(添加依赖)HttpApi项目(包括 API 控制器),客户端可以响应 HTTP API 调用;
  • HTTP API 控制器使用Application.Contracts项目中定义的服务接口,而这些接口由Application项目实现,这就是为什么我们需要在HttpApi.Host项目中引用Application项目,而Application往下依赖的是Domain层,通过它来执行业务逻辑。
  • HttpApi.Host项目还引用了该EntityFrameworkCore项目,因为我们在运行时需要一个数据层。该EntityFrameworkCore项目将实体映射到数据库中的表,并实现了Domain项目中定义的存储库接口。

请注意,Application.Contracts项目,以及Domain.Shared项目由客户端程序Main Website共享(以及Domain.Shared项目是间接被共享),因此它们可以依赖相同的应用程序接口进行通信。

我们现在已经了解了主站应用程序,下一部分介绍管理员后台:

Admin Application(管理员站)

管理员后台站点的前端采用的是Blazor WebAssembly技术,它有一组不同的 API、UI 页面、授权规则、缓存要求等。它有不同的应用层和 HTTP API 层,共享相同的领域层,使用相同的领域逻辑和相同的数据库。

如下图所示:
探索ABP的EventHub解决方案-LMLPHP

此图很简单。Admin.Web项目(即 Blazor WebAssembly )引用Admin.HttpApi.Client项目,因为它需要调用远程 HTTP API。而项目Admin.HttpApi.Client依赖于Admin.Application.Contracts项目(内部依赖于Domain.Shared项目),目的是要使用其中定义的应用服务接口。

Admin HTTP API(管理员站 API)

管理员站点调用Admin HTTP API。它运行着管理员后台的应用逻辑。下图显示了根项目Admin.HttpApi.Host及其直接和间接依赖项:
探索ABP的EventHub解决方案-LMLPHP

该图与Main HTTP API非常相似。区别在于他们具有不同的 HTTP API 和应用层。但是使用相同的领域和数据库集成 (EntityFrameworkCore) 层。

认证服务器

Authentication Server的根项目是IdentityServer,依赖关系如下:
探索ABP的EventHub解决方案-LMLPHP

IdentityServer项目和主站一样,也引用Web.Theme,它还引用了EntityFrameworkCore项目。通过引用EntityFrameworkCore项目,也间接引用了DomainDomain.Shared项目。

后台服务

BackgroundServices项目具有下图所示的依赖项:

BackgroundServices项目引用EntityFrameworkCore,以便操作数据库,它还可以使用领域对象(实体、域服务)来执行后台任务。

我们已经介绍完了解决方案中的所有项目。现在,我们准备在本地开发环境中运行它们。

如果你想要在您的本地环境中运行解决方案,请按照以下步骤操作。

克隆 GitHub 存储库

首先,你需要在本地计算机上克隆 GitHub 存储库。该存储库位于https://github.com/volosoft/eventhub,可以使用以下命令进行克隆(需要安装 Git 工具):

git clone https://github.com/volosoft/eventhub.git

或者,导航到https://github.com/volosoft/eventhub,单击Code按钮,然后单击Download ZIP,如以下屏幕截图所示:
探索ABP的EventHub解决方案-LMLPHP

三、方案运行

准备基础环境

该解决方案需要RedisPostgreSQL服务器。在etc/docker夹中的存储库包含docker-compose文件。如果您的计算机上安装了 Docker,可以直接执行文件夹中的up.ps1文件来运行这些服务器。如果您不能在您的计算机上使用 PowerShell,您可以在文本编辑器中打开并复制脚本,然后打开命令行终端并切换到etc/docker目录中执行它。第一次运行,下载 Docker 镜像可能需要几分钟。如果您不想使用 Docker,则需要在您的机器上手动安装RedisPostgreSQL

打开解决方案

请在 Visual Studio 或其他与 .NET 兼容的 IDE 中打开前面下载的解决方案EventHub.sln

创建数据库

该解决方案有一个EventHub.DbMigrator项目,运行此应用程序(对于 Visual Studio,右键单击它并选择设为启动项目,然后按 Ctrl+F5)。它将创建一个数据库并初始化一些数据。

运行应用程序

我们现在准备好启动程序。您可以按以下顺序运行项目(对于 Visual Studio,右键单击每个项目,选择设为启动项目,然后按 Ctrl+F5

  • EventHub.IdentityServer
  • EventHub.HttpApi.Host
  • EventHub.Web
  • EventHub.Admin.HttpApi.Host
  • EventHub.Admin.Web
  • EventHub.BackgroundServices
    请使用admin用户名和1q2w3E*密码进行登录。当然,您可以在 UI 上创建其他用户。

微软的Tye使得运行多个应用程序变得更加容易。下面介绍这种运行方式:

使用 Tye 项目

如果你不想要开发或调试解决方案但只想运行它,您可以使用 Microsoft的Tye项目来运行它,而无需打开 IDE。Tye是一个 .NET 全局工具,用于通过简单的配置简化运行此类分布式应用程序。EventHub 解决方案支持使用Tye配置,您需要做的就是安装Tye并运行它。

在使用之前Tye,您仍然需要准备基础环境(同上),然后使用EventHub.DbMigrator创建数据库(打开命令行终端并,并切换到目录src/EventHub.DbMigrator,运行以下命令:

dotnet run

数据库准备好后,您可以在命令行终端中执行以下命令来安装Tye

dotnet tool install -g Microsoft.Tye

在撰写本书时,Tye项目仍处于预览阶段。您可能需要指定最新的预览版本(您可以在 NuGet 上找到此内容,网址为https://www.nuget.org/packages/Microsoft.Tye)。请参阅以下代码片段:

dotnet tool install -g Microsoft.Tye --version "0.10.0-alpha.21420.1"

点击以了解如何安装Tye

Tye需要在您的计算机上预先安装 Docker。全部安装完成后,您可以运行以下命令启动应用程序(如果IDE已打开,建议先关闭IDE):

tye run

第一次运行需要一些时间。完成后,您可以打开浏览器并导航至http://127.0.0.1:8000打开Tye Dashboard,如下图:
探索ABP的EventHub解决方案-LMLPHP

Tye仪表板用于观看实时应用及其日志。您可以单击Bingdings列上的链接以打开任何应用。web是系统的主站

当您的解决方案包含多个需要一起运行的应用时,Tye 是一个很方便的工具。您还可以dotnet watch对项目进行配置,以便在您更改项目时自动重新加载(或使用 .NET 6.0 热加载)。请参阅 Microsoft 的以了解更多信息。

概括

EventHub 是一个基于 ABP 框架的完整的、真实的实时示例应用。而且已经发布在openeventhub.com上,我们可以在GitHub上随时发送错误报告、推送请求和拉取代码。

在本章中,我们重点介绍的解决方案的整体架构,以便您了解如何探索代码库和运行解决方案。下一章将参考该解决方案,同时介绍一些 ABP 特性和概念。

EventHub 是使用多个应用构建的一个很好的例子。这也是理解 ABP 分层模型以及如何在不同应用中重用这些层的一个示例。

截止目前你可能还不了解 EventHub 解决方案的所有细节,因为我们还没有解释模块化系统、数据库集成、动态 C# 客户端代理以及所有其他 ABP 功能。

在下一章中,我们将探索 ASP.NET Core 和 ABP 框架的基本模块,以了解如何配置和初始化应用程序。

希望以上分享对你有所帮助,感谢您的捧场。
作者: 张飞洪[厦门]
QQ群: 共享交流群
我的: 知识星球
打赏支持
05-10 10:52