1. 程式人生 > >ABP 適用性改造 - 精簡 ABP CLI 生成的專案結構

ABP 適用性改造 - 精簡 ABP CLI 生成的專案結構

## Overview 不管是公司或者個人都會有不同的開發習慣,通過建立專案模板,既可以使開發人員聚焦於業務功能的開發,也可以在一定程度上統一不同開發人員之間的開發風格。在使用 ABP 框架的過程中,對於 ABP 生成的預設專案模板,類庫多,附加功能多,是目前在部門內部推行 ABP 過程中遇到的問題。因此,本篇文章將針對 ABP 預設生成的模板專案進行精簡,構建出一個簡化版的 ABP 專案模板 模板原始碼地址:https://github.com/danvic712/ingos-abp-api-template ## Step by Step 在精簡專案結構之前肯定需要一個由 ABP CLI 生成的預設專案模板供我們進行參考,建立 ABP 專案主要有如下的兩種方式進行 第一種,通過使用 [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) 這麼一個 dotnet tool 來建立一個基礎專案,只需要將 ABP CLI 全域性安裝到電腦上,就可以通過腳手架來生成所需專案 ```sh -- 全域性安裝 ABP CLI dotnet tool install -g Volo.Abp.Cli -- 全域性更新 ABP CLI dotnet tool update -g Volo.Abp.Cli ``` 當安裝完成之後,輸入 `abp help` 就可以檢視該腳手架提供的功能,例如這裡我們需要通過 `abp new` 命令來建立專案,同時基於不同的需求,在建立專案時附加不同的引數即可 ![ABP CLI](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215245439-891560907.png) 第二種,則是直接通過官網([https://abp.io/get-started](https://abp.io/get-started))進行下載,本篇文章中所使用到的專案模板就是使用該方法,直接在官網上下載的模板基礎上進行調整的 ![建立專案](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215301676-2059612922.png) 在官網建立專案時需要輸入專案的相關資訊,因為這裡需要改造的是 Web API 專案,所以 UI 框架選擇了 Angular,同時,因為預設的 ABP 模板會把 IdentityServer 和 API 專案混在一起,所以這裡我會把這兩塊的功能進行拆分,確定專案型別無誤之後,點選現在建立按鈕,等待瀏覽器提示有檔案需要下載即可 ### 2.1、執行模板專案 解壓下載完成的安裝包,如果你和我建立的專案選項相同的話,這裡會包含兩個資料夾,因為僅針對後端專案進行調整,這裡只關注 aspnet-core 資料夾中的內容即可。在改造之前,我們先依據官方文件中的使用說明來進行操作,確保模板是可以正常執行起來之後再進行後續的調整。 ![模板資料夾結構](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215314530-387999668.png) #### 2.1.1、調整資料庫連線字串 在 ABP 生成的模板專案中,整個專案的配置檔案 appsettings.json 檔案存在於三個地方,`.DbMigrator`、`.HttpApi.Host`、`.IdentityServer`,先不去關注這三個專案的具體作用,首先將這三處配置檔案中的資料庫連線字串修改為實際使用的配置資訊 ```json "ConnectionStrings": { "Default": "Server=localhost;Port=3306;Database=IngosAbpTemplate;Uid=root;Pwd=myPassword;" }, ``` #### 2.1.2、執行資料庫遷移 在調整完資料庫連線配置之後,就可以執行資料庫的遷移操作,從而實現初始化專案模板中內建的一些資料表結構 or 初始化資料 這裡,將 `.DbMigrator ` 設定為啟動專案,直接執行,等待程式的執行完成即可。此時,開啟你所使用的 DBMS 工具,可以看到模板專案中定義的表已經遷移到了我們指定的資料庫中 ![執行資料庫遷移](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215330791-35441102.png) 可以看到,整個模板專案中包含了很多的東西,絕大多數的功能都不會是我們平常在開發業務功能時經常能夠使用到的 #### 2.1.3、執行程式 當資料庫遷移成功之後就可以正式運行了,在這個模板程式中存在著兩個 Web 應用,`.HttpApi.Host`、`.IdentityServer`,分別對應於 API 介面的宿主以及 IdentityServer 的宿主,因為後續會移除掉 IdentityServer 相關的功能,所以這裡就只執行 `.HttpApi.Host` 這一個站點了 將 `.HttpApi.Host` 設定為啟動程式,這裡並不會進行除錯,所以直接通過 Ctrl + F5 執行,專案會自動開啟 swagger 頁面 ![Swagger](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215342279-699312091.png) ### 2.2、精簡專案功能 當程式可以執行起來之後,就可以針對模板專案進行精簡及改造,這裡主要包含兩塊的內容,精簡模板的功能以及簡化專案的結構 #### 2.2.1、精簡模板功能 首先這裡會移除掉 `.IdentityServer` 這個 Web 專案以及目前使用不到的 test 資料夾,從上面執行的 swagger 頁面中就可以看到,初始化的模板中包含了一些業務功能開發中可能用不到的功能,而這些功能則是包含在專案所引用的 ABP 類庫中的。因此,對於模板功能的精簡則是將引用的一些用不到的 `Volo.Abp.*` 類庫進行去除,僅保留我們所需的部分 這裡我移除了下列的程式集引用,重新編譯解決方案,不出意外會報很多的錯誤,因為具體的排錯過程會涉及到很多,不太好用文字進行描述,所以這裡就跳過了 - Volo.Abp.Account.* - Volo.Abp.Identity.* - Volo.Abp.IdentityServer.* - Volo.Abp.PermissionManagement.* - Volo.Abp.TenantManagement.* - Volo.Abp.FeatureManagement.* - Volo.Abp.SettingManagement.* - Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy ![報錯資訊](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215359743-539746997.png) 這裡對於模板專案中的功能基本上都移除了,只保留了 audit 日誌、後臺任務、郵件通知、物件對映、EF Core 這類的基礎服務 總結來說,對於移除功能後導致的編譯報錯,只需要將相關的類檔案、引用直接刪除就好,而對於功能移除之後產生的程式碼問題,就需要具體分析了,這類的問題基本上是初始化資料(DataSeed)的功能,我這邊採取的是直接移除相關的功能 至此,當你進行到這一步時,也就可以順勢將 `.DbMigrator` 這個專門用於資料庫遷移的控制檯應用進行移除了,而對於遷移的這個功能,在下面的內容中我也將補充到別的類庫上 哦對了,在移除上面的功能之後,你還需要在如下的類庫中新增對應的 ABP 程式集引用,從而確保程式可以編譯通過 - `.Application` 引用 `Volo.Abp.Ddd.Application` - `.Domain.Shared` 引用 `Volo.Abp.Validation` - `.HttpApi` 引用 `Volo.Abp.AspNetCore.Mvc` - `.HttpApi.Client` 引用 `Volo.Abp.Http.Client` 如果不出意外的話,你的應用已經能夠編譯成功,並且可以再次運行了,從 swagger 也就可以看出,整個模板去掉了絕大多數的功能。當然,如果你覺得這個過程比較麻煩的話,也可以直接使用文章開頭所列到的 github 的專案,然後在上面基於你的需求進行調整即可 ![精簡功能](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215416771-117045153.png) ### 2.3、簡化專案結構 讓我們再回到最原始的後端模板專案中,整個後端解決方案的專案全域性結構如下所示 ![解決方案結構](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215433461-511092259.png) 因為移除了單元測試的相關類庫,從專案依賴關係圖中就可以看到,整個解決方案中,包含了三個最頂層的專案,`.IdentityServer`、`.HttpApi.Host`、`.DbMigrator`,其它類庫之間通過相互引用,構建出專案的分層基礎 ![依賴關係](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215445243-1261852038.png) 當然,在上面進行模板功能的精簡時,已經將 `.IdentityServer`、`.DbMigrator` 這一塊進行了整體的移除 #### 2.3.1、合併 EntityFramework Core 相關功能類庫 因為這裡選擇了 EntityFramework Core(以下簡稱 EF Core)作為專案的 ORM,如果使用 Code First 模式的話,不可避免的會使用到 migrations 這樣一個遷移的操作,在原始的模板中,存在著如下的三個類庫與之存在關聯 - .DbMigrator:控制檯程式,主要是為了進行資料庫的遷移工作(migration) - .EntityFrameworkCore:整合 EF Core 到專案中,定義 DbContext 和領域中的資料訪問倉儲(Repository),在整個專案中提供資料持久化以及資料訪問 - .EntityFrameworkCore.DbMigrations:執行 EF Core 的遷移 可以看到,ABP 作為一個模組化的框架,對於每個類庫的使用用途定義的非常清楚,但是,在實際的開發中,對於正式環境資料庫的操作基本上都是交由 DBA 來執行的,EF Core 的 migration 更多的是在開發時進行使用。同時,如果真的這樣劃分的話,至少我遇到的絕大多數開發人員都是會叫的 介於上面已經將 `.DbMigrator` 進行了移除,因此,這裡將對於 EF Core 的相關操作全部合併到 `.EntityFrameworkCore` 這個類庫中 為了方便起見,我們先把 `.EntityFrameworkCore.DbMigrations` 中的檔案全部拷貝一份到 `.EntityFrameworkCore` 這個類庫中,然後直接在解決方案中移除掉原有的類庫後再進行調整 PS:這裡的 Migrations 資料夾以及 `.EntityFrameworkCore.DbMigrations` 的模組類就可以直接刪除了,畢竟上面我們精簡了模板的功能後,絕大多數的表也不復存在了 ,後面在類庫合併後也會重新執行資料庫遷移的操作 ![合併 EF Core 相關類庫](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215509346-589494528.png) 因為現在會在 `.EntityFrameworkCore` 上執行 migration 的操作,所以這裡需要新增上 EF Core 官方的 Design 元件包 ```sh Install-Package Microsoft.EntityFrameworkCore.Design ``` 對於從 `.DbMigrations` 這個類庫,其實是存在引用關係的,當整體刪除之後,我們需要在 `.HttpApi.Host` 上新增對於 `.EntityFrameworkCore` 這個類庫的引用。同時,對於拷貝過來的檔案,其實是存在功能重複的問題,所以這裡我們需要對這些檔案進行合併歸納 首先,則是需要對於 DbContext 這個資料庫上下文物件進行合併。從下圖中可以看到,兩個 DbContext 主要在配置實體對映關係的地方有所差異,因此這裡直接將 `MigrationsDbContext` 這個類中關於 ABP 內建框架的實體對映配置拷貝過去即可,然後就可以直接刪除了 ![合併 DbContext](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215527217-1226026375.png) 對於每個 ABP 類庫來說,都會存在一個入口的模組類,這裡對比後就可以發現,直接將 `EntityFrameworkCoreDbMigrationsModule` 這個模組類刪除即可,然後你需要將 `.HttpApi.Host` 專案中引用的這個模組型別改為 `EntityFrameworkCoreModule` 此時,編譯解決方案,報錯的問題主要是因為引用了已經刪除的 DbContext,這裡直接替換成現在使用的即可 ![修復 DbContext 引用錯誤的問題](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215543281-2131884334.png) 這裡還有一項需要注意,從上圖中的第 27 行可以看到,這裡獲取的是 `.DbMigrator` 這個控制檯應用中的配置檔案,所以這裡也需要同步修改成獲取 `.HttpApi.Host` 專案中的配置檔案 自此,涉及到 EF Core 相關功能的類庫就合併完成了,定位到 `.EntityFrameworkCore` 這個類庫,在控制檯中就可以通過 migrations 命令來執行資料庫的遷移工作。因為已經執行過一次了,所以直接將原來的庫刪除即可 ```shell -- 1、建立遷移檔案 dotnet ef migrations add Initialize -- 2、應用到資料庫中 dotnet ef database update ``` PS:這裡使用的是 EF Core tools 這麼一個 dotnet tool,如果控制檯提示你找不到命令的話,你需要先安裝該工具到你的電腦上 ```shell dotnet tool install --global dotnet-ef ``` 等待遷移工作的完成,資料庫也重新生成了對應的表,此時再次執行專案,系統執行無誤後即可進行後續的操作 ![遷移完成](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215600045-1431073680.png) #### 2.3.2、合併 API 宿主相關功能 一般來說,我們會在 ASP.NET Core 專案中來定義 Controller,並以此作為整個介面專案的宿主程式,在 ABP 中,涉及到 API 介面的包含了如下的三個類庫 - .HttpApi:定義 API 介面的 controller - .HttpApi.Client:用於設定其它 C# 程式呼叫該 API 的 HTTP 代理 - .HttpApi.Host:API 介面的宿主程式 這裡的 `.HttpApi.Client` 的類庫我們使用不到,所以直接刪除即可,對於剩下的兩個類庫將進行合併,統一至 `.HttpApi.Host` 這個 ASP.NET Core 專案中 對於這兩個類庫的合併很簡單,直接將 `.HttpApi` 專案中的類檔案直接拷貝到 `.HttpApi.Host` 中即可,然後將模組類中的配置進行移動,最後直接刪除 `.HttpApi` 類庫,並將相關引用刪除即可 ![合併 API 相關功能](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215618078-1610711228.png) 至此,整個模板專案的簡化也就結束了,在保留 ABP 的設計思想下,基於開發現狀,構建了一個相對單一的模板專案,調整後的專案引用關係圖如下所示 ![專案引用關係圖](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215635359-1052040308.png) ### 2.4、搭建專案腳手架 當整個調整完成之後,後續再建立一個新的專案時不可能再執行一次這樣的操作,因此這裡會建立一個 nuget 包進行釋出,這樣後面就可以直接通過 dotnet cli 命令來直接建立專案來使用 對於搭建專案模板的過程這裡就不詳細描述了,如果有需要的同學,可以參考部落格園中的這一篇文章([打造自己的.NET Core專案模板](https://www.cnblogs.com/catcher1994/p/10061470.html)),在這個過程中我們需要新建兩個檔案 `template.json` 以及 `Ingos.Abp.Templates.csproj` ,調整後的專案資料夾結構如下所示 ![專案腳手架結構](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215650855-1919966128.png) 這裡列出來了我目前使用的配置,你可以進行參考,如果你需要新增別的引數的話,可以參考官網文件([dotnet new 自定義模板](https://docs.microsoft.com/zh-cn/dotnet/core/tools/custom-templates)) ```json { "$schema": "http://json.schemastore.org/template", "author": "Danvic Wang", "classifications": [ "Web/WebAPI" ], "name": "Ingos Web API with ABP Framework", "identity": "Ingos.Abp.Templates", "shortName": "ingos-abp", "tags": { "language": "C#", "type": "project" }, "sourceName": "IngosAbpTemplate", "preferNameDirectory": true } ``` ```xml Template 1.0.1 Ingos.Abp.Templates Ingos.Abp.Templates Danvic Wang Ingos Web API with ABP Framework dotnet-new;templates;abp;domain-driven-design net5.0 true false content $(NoWarn);NU5128 MIT Copyright (c) 2021 Danvic Wang logo.png Ingos.Abp.Templates
Danvic Wang https://github.com/danvic712/ingos-abp-api-template https://github.com/danvic712/ingos-abp-api-template git
True
``` 當配置定義完成之後,定位到 `Ingos.Abp.Templates.csproj` 所在的路徑,執行 `dotnet pack -o .` 命令即可生成一個包含版本號的 `.nupkg` 檔案,之後就可以將該檔案上傳到公有 or 私有的 nuget 倉庫中供別人進行下載使用 以我這裡建立的專案為例,因為我已經上傳到 nuget 官方倉庫上了,因此,你可以使用如下的命令進行安裝 ```shell dotnet new -i Ingos.Abp.Templates ``` ![安裝專案模板](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215709845-1091050314.png) 安裝完成後就可以通過 dotnet 命令進行專案的建立,在最新版的 VS 中,你也可以直接通過 IDE 來使用該模板進行專案的建立,相對來說也就更方便了,至此整個模板的精簡的操作也就結束了,希望可以對你有所幫助 ![通過 VS 建立專案](https://img2020.cnblogs.com/blog/1310859/202103/1310859-20210317215721333-2042606546.png)