ABP vnext模塊化架構的最佳實踐的實現

在上一篇文章《手把手教你用Abp vnext構建API接口服務》中,咱們用ABP vnext實現了WebAPI接口服務,可是並不是ABP模塊化架構的最佳實踐。我自己也在學習ABP,我認爲ABP新手應該從最佳實踐開始學習,能夠少走不少彎路,因此寫了這篇最佳實踐來作個總結,同時給其餘朋友們提供一點參考。html

1、什麼是模塊化架構的最佳實踐

ABP是一個包含許多nuget包的模塊化框架。它提供了一個完整的基礎架構來開發你本身的具備實體、服務、數據庫集成、API、 UI組件等等功能的應用程序模塊。
模塊化架構的最佳實踐就是按功能的劃分建立相應的模塊實現的服務,必要時能夠把模塊發佈到nuget,由其餘模塊安裝組合成新的服務或單體應用。這樣就能夠複用現有的模塊功能,快速的交付產品,告別996。mysql

2、模塊化架構的最佳實踐說明

這部份內容所有來自於模塊化架構最佳實踐 & 約定,有興趣的朋友能夠去官方文檔查看。若是已經很熟悉ABP分層了,能夠直接閱讀第三部分。git

一、解決方案結構:
  1. 爲每一個模塊建立一個單獨的解決方案。將解決方案命名爲CompanyName.ModuleName。
  2. 一個模塊作爲分層項目開發,由於它有幾個包(項目)是相互關聯的。每一個包都有本身的模塊定義文件,並顯式聲明所依賴的包/模塊的依賴關係。
二、模塊分層和包之間的關係
下面展現了一個分層良好的模塊中的包以及它們之間的依賴關係:

領域層

將領域層劃分爲兩個項目:github

  1. Domain.Shared 包(項目) 命名爲CompanyName.ModuleName.Domain.Shared,包含常量,枚舉和其餘類型,它不能包含實體、存儲庫、域服務或任何其餘業務對象。能夠安全地與模塊中的全部層使用。此包也能夠與第三方客戶端使用。
  2. Domain 包(項目) 命名爲CompanyName.ModuleName.Domain,包含實體、倉儲接口、領域服務接口及其實現和其餘領域對象。Domain 包依賴於 Domain.Shared 包。
應用服務層

將應用服務層劃分爲兩個項目:web

  1. Application.Contracts 包(項目) 命名爲CompanyName.ModuleName.Application.Contracts,包含應用服務接口和相關的數據傳輸對象(DTO)。 Application contract 包依賴於 Domain.Shared 包。
  2. Application 包(項目)命名爲CompanyName.ModuleName.Application,包含應用服務實現。Application 包依賴於 Domain 包和 Application.Contracts 包。
基礎設施層
  1. 爲每一個orm/數據庫集成建立一個獨立的集成包,好比Entity Framework Core 和 MongoDB。例如,建立一個抽象Entity Framework Core集成的CompanyName.ModuleName.EntityFrameworkCore 包。ORM 集成包依賴於 Domain 包。不推薦依賴於orm/數據庫集成包中的其餘層.
  2. 爲每一個主要的庫建立一個獨立的集成包, 在不影響其餘包的狀況下能夠被另外一個庫替換.
HTTP 層
  1. 建立命名爲CompanyName.ModuleName.HttpApi的HTTP API包,爲模塊開發REST風格的HTTP API。
    • HTTP API 包只依賴於 Application.Contracts 包。不要依賴 Application 包。
    • 爲每一個應用服務建立一個Controller (一般經過實現其接口)。這些控制器使用應用服務接口來委託操做。它根據須要配置路由,HTTP方法和其餘與Web相關的東西。
  2. 建立一個爲HTTP API包提供客戶端服務的HTTP API Client包,它的命名爲Companyname.ModuleName.HttpApi.Client。這些客戶端服務將應用服務接口實現遠程端點的客戶端。
    • HTTP API Client包僅依賴於 Application.Contracts包。
    • 推薦使用ABP框架提供的動態代理HTTP C#客戶端的功能。
Web 層

建立命名爲CompanyName.ModuleName.Web的Web包。 包含頁面、視圖、腳本、樣式、圖像和其餘UI組件。Web包僅依賴於HttpApi包。sql

3、實現模塊化架構的最佳實踐

開發環境:Mac Visual Studio Code
SDK:dotnet core 3.1
數據庫:PostgreSQL數據庫

建立項目文件夾,而後進入改文件夾的命令目錄執行如下命令建立項目

在上一篇文章中引入的是Volo.Abp.Identity的包,如今改用Volo.Abp.DDD的包,更簡潔。api

/**建立解決方案**/
dotnet new sln
/**建立模塊分層**/
dotnet new classlib -o src/Lemon.Account.Domain.Shared
dotnet new classlib -o src/Lemon.Account.Domain
dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore
dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore.DbMigrations
dotnet new classlib -o src/Lemon.Account.Application.Contracts
dotnet new classlib -o src/Lemon.Account.Application
dotnet new classlib -o src/Lemon.Account.HttpApi
dotnet new classlib -o src/Lemon.Account.HttpApi.Client
dotnet new web -o src/Lemon.Account.Host

/**加入解決方案**/
dotnet sln Lemon.Account.sln add src/Lemon.Account.Domain.Shared
dotnet sln Lemon.Account.sln add src/Lemon.Account.Domain
dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore
dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore.DbMigrations
dotnet sln Lemon.Account.sln add src/Lemon.Account.Application.Contracts
dotnet sln Lemon.Account.sln add src/Lemon.Account.Application
dotnet sln Lemon.Account.sln add src/Lemon.Account.HttpApi
dotnet sln Lemon.Account.sln add src/Lemon.Account.HttpApi.Client
dotnet sln Lemon.Account.sln add src/Lemon.Account.Host

/**分層間互相引用**/
dotnet add src/Lemon.Account.Domain/Lemon.Account.Domain.csproj reference src/Lemon.Account.Domain.Shared/Lemon.Account.Domain.Shared.csproj
dotnet add src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj reference src/Lemon.Account.Domain/Lemon.Account.Domain.csproj
dotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj reference src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj
dotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj reference src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj
dotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj reference src/Lemon.Account.Domain/Lemon.Account.Domain.csproj
dotnet add src/Lemon.Account.HttpApi/Lemon.Account.HttpApi.csproj reference src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.Application/Lemon.Account.Application.csproj
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.HttpApi/Lemon.Account.HttpApi.csproj

/**添加nuget依賴包**/
dotnet add src/Lemon.Account.Domain.Shared/Lemon.Account.Domain.Shared.csproj package Volo.Abp.Validation
dotnet add src/Lemon.Account.Domain/Lemon.Account.Domain.csproj package Volo.Abp.Ddd.Domain
dotnet add src/Lemon.Account.Domain/Lemon.Account.Domain.csproj package Lemon.Common

dotnet add src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj package Volo.Abp.EntityFrameworkCore
dotnet add src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj package Volo.Abp.EntityFrameworkCore.PostgreSql

dotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj package Volo.Abp.EntityFrameworkCore
dotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj package Volo.Abp.EntityFrameworkCore.PostgreSql
dotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj package Microsoft.EntityFrameworkCore.Design

dotnet add src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj package IdentityModel
dotnet add src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj package Volo.Abp.Ddd.Application.Contracts

dotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj package Volo.Abp.Ddd.Application
dotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj package Volo.Abp.AutoMapper

dotnet add src/Lemon.Account.HttpApi/Lemon.Account.HttpApi.csproj package Volo.Abp.AspNetCore.Mvc

dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Volo.Abp.AspNetCore.Mvc
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Swashbuckle.AspNetCore
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Microsoft.AspNetCore.DataProtection.StackExchangeRedis
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Microsoft.Extensions.Caching.StackExchangeRedis
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.AspNetCore
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.Settings.Configuration
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.Sinks.Async
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.Sinks.File
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Volo.Abp.AspNetCore.Serilog
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Volo.Abp.Autofac
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package IdentityServer4.AccessTokenValidation
dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj
實現領域層

在Domain建立實體類及其約束關聯,具體代碼請看UserData類,此處再也不詳細說明。瀏覽器

實現基礎設施層

在EntityFrameworkCore建立AccountDbContext類和LemonAccountDbContextModelCreatingExtensions類。請特別關注LemonAccountDbContextModelCreatingExtensions類,主要是用來定義實體在數據庫表中的字段屬性。安全

實現應用服務層
實現httpapi
用swagger調試接口

進入Host目錄,執行命令

dotnet watch run


服務啓動成功,在瀏覽器打開連接http://localhost:5000/swagger/index.html,開始調試帳號註冊和驗證接口。結果以下:



4、模塊化架構的最佳實踐的好處

使用模塊化架構的好處有幾點:

  1. 能夠方便的更換模塊
    好比我如今用的數據庫是PostgreSQL,若是想要更換成MySQL,只要以EntityFrameworkCore層爲基礎,新增一個MySQL鏈接庫,就能夠在不改變業務邏輯的前提下快速的切換數據庫。
dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore.MySQL
dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations
dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore.MySQL
dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations

dotnet add src/Lemon.Account.EntityFrameworkCore.MySQL/Lemon.Account.EntityFrameworkCore.MySQL.csproj reference src/Lemon.Account.Domain/Lemon.Account.Domain.csproj
dotnet add src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations.csproj reference src/Lemon.Account.EntityFrameworkCore.MySQL/Lemon.Account.EntityFrameworkCore.MySQL.csproj

dotnet add src/Lemon.Account.EntityFrameworkCore.MySQL/Lemon.Account.EntityFrameworkCore.MySQL.csproj package Volo.Abp.EntityFrameworkCore.MySQL

dotnet add src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations.csproj package Microsoft.EntityFrameworkCore.Design

最後再修改ConnectionStrings default爲mysql的鏈接,修改LemonAccountHostModule的依賴項LemonAccountEntityFrameworkCoreDbMigrationsModule爲MySQL

  1. 單體應用和微服務無縫切換
    模塊開發完成後,通常看成微服務來部署;或者把模塊發佈到nuget,在單體應用的各個分層中引入模塊,多個模塊在單體應用中的應用就構成了一個完整系統服務。

  2. 模塊複用
    因爲模塊是發佈到nuget的,因此若是有新的項目須要用到相同功能的,能夠直接從nuget引入安裝,無需重複開發或者複製代碼。

  3. 自動API控制器

  4. 動態 C# API 客戶端

GiHub地址:https://github.com/huangbenq/abp-samples

參考文檔:

  1. 模塊化:https://docs.abp.io/zh-Hans/abp/latest/Module-Development-Basics
  2. 最佳實踐:https://docs.abp.io/zh-Hans/abp/latest/Best-Practices/Index
  3. 自動API控制器:https://docs.abp.io/zh-Hans/abp/latest/API/Auto-API-Controllers
相關文章
相關標籤/搜索