在上一章中,我們構建了一個簡單的全棧 Web 應用程式,我們已經看到了使用 ABP 框架開發應用的典型流程,在接下來,我們將使用 ABP 框架建立更高階的應用程式。
給出具有現實世界複雜性的例子並不容易,考慮到這一點,我們準備了一個使用 ABP 框架構建的完整的、真實的參考應用程式:EventHub。它是開源的,可在 GitHub 上免費獲得。
EventHub 解決方案可在openeventhub.com上實時瀏覽。您可以嘗試一下來探索它。我們已經建立了持續整合/持續開發(CI/CD) 管道,會實時進行網站更新,因為我們正在開發它並獲得社群的貢獻。歡迎隨意檢視其原始碼,提交錯誤報告或功能請求!顧名思義,這是一個開放的平臺。
在本文中,我們將在以下部分中研究 EventHub 解決方案:
- 應用介紹
- 架構探索
- 方案執行
一、應用介紹
活動中心是一個平臺,用於組織建立活動。您可以親自線上建立活動。以下截圖取自openeventhub.com網站的主頁:
您可以瀏覽主頁上即將舉行的 活動部分。單擊一個事件瞭解詳細資訊並註冊該事件。在活動開始之前或活動時間更改之時,您會收到電子郵件通知。
這是建立新事件頁面的另一個截圖:
您可以在此頁面上選擇您擁有的組織,設定標題、時間和描述,選擇封面圖片,並確定有關您正在組織活動的其他詳細資訊。
如果您想了解更多資訊,請在openeventhub.com註冊並探索該平臺。在本書中,我想討論的是技術細節而不是業務功能。讓我們從大局開始,瞭解整個方案的架構。
二、架構探索
整體架構圖
下面是解決方案整體架構圖:
如圖所示,有六個應用程式和一個資料庫,下面提供了更多的資訊:
- 身份驗證伺服器:此服務用於登入、註冊和管理使用者帳戶。它基於 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) 協議將使用者重定向到**身份驗證伺服器。**下圖顯示了登入過程:
它的邏輯順序是這樣的:
- 當使用者想要訪問主站時 (1),主站將使用者重定向到身份驗證服務 (2)。
- 身份驗證服務有一個登入頁面,使用者可以輸入使用者名稱和密碼或註冊為新使用者。登入完成後,使用者將重定向回主站,並返回授權碼 (3) 和 (4)。
- 然後,主站使用獲得的授權碼向伺服器執行令牌請求 (5)。
- 身份驗證服務返回一個識別符號(包含一些使用者資訊,例如使用者名稱、ID、電子郵件等)和一個訪問令牌 (6)。
- 主站將訪問令牌儲存在 cookie 中(管理員後臺將令牌儲存在瀏覽器的本地儲存中),以便在下一個請求中獲取。在接下來的請求中,它從 cookie 中獲取訪問令牌並將其新增到 HTTP 請求頭中,同時對Main HTTP API執行 HTTP 請求 (7)。
- Main HTTP API 驗證訪問令牌 (8) 並授權請求。
所有這些過程都由 ABP的Account
和IdentityServer
模組完成。
探索解決方案
EventHub.NET 解決方案由多個專案組成,按應用型別分組,如下圖所示:
該解決方案有兩個應用層和一個領域層,以及相應的 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
開始:
該Web
專案依賴於Web.Theme
,它實現了 EventHub 的 UI 主題。Web.Theme
是一個單獨的專案,因為它同時被Authentication Server複用。
專案Web
也依賴於HttpApi
專案。我們可以在Web專案的客戶端 (JavaScript) 中呼叫這些 API,當您通過HttpApi.Client
呼叫 HTTP API 時,請求將重定向到 Main HTTP API (後端)。
[success] 請注意,
HttpApi
和HttpApi.Client
都引用了Application.Contacts
專案。
HttpApi
引用.Contracts
介面層,而HttpApi.Client
使用 ABP 的動態 C# 代理實現了這些介面,並通過執行HTTP遠端呼叫Main HTTP API。
Main HTTP API(主站API)
主站使用Main HTTP API作為後端 API。它包含應用領域邏輯。下圖顯示了根專案HttpApi.Host
及其直接或間接依賴項:
- 通過引用(新增依賴)
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 層,共享相同的領域層,使用相同的領域邏輯和相同的資料庫。
如下圖所示:
此圖很簡單。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
及其直接和間接依賴項:
該圖與Main HTTP API非常相似。區別在於他們具有不同的 HTTP API 和應用層。但是使用相同的領域和資料庫整合 (EntityFrameworkCore
) 層。
認證伺服器
Authentication Server的根專案是IdentityServer
,依賴關係如下:
IdentityServer
專案和主站一樣,也引用Web.Theme
,它還引用了EntityFrameworkCore
專案。通過引用EntityFrameworkCore
專案,也間接引用了Domain
和Domain.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,如以下螢幕截圖所示:
三、方案執行
準備基礎環境
該解決方案需要Redis和PostgreSQL伺服器。在etc/docker
夾中的儲存庫包含docker-compose
檔案。如果您的計算機上安裝了 Docker,可以直接執行資料夾中的up.ps1
檔案來執行這些伺服器。如果您不能在您的計算機上使用 PowerShell,您可以在文字編輯器中開啟並複製指令碼,然後開啟命令列終端並切換到etc/docker
目錄中執行它。第一次執行,下載 Docker 映象可能需要幾分鐘。如果您不想使用 Docker,則需要在您的機器上手動安裝Redis和PostgreSQL。
開啟解決方案
請在 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 上建立其他使用者。
[success] 請注意,當您執行多個應用程式時,Visual Studio 會出現一些問題。有時,以前執行的應用程式可能會停止。在這種情況下,請再次執行停止的應用程式。
微軟的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,如下圖:
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 框架的基本模組,以瞭解如何配置和初始化應用程式。