ABP vNext微服务架构详细教程——基础服务层
1
服務創建
在除身份管理相關服務以外的其他業務服務中,我們不需要包含用戶角色權限管理功能模塊,ABP vNext框架為我們提供了模塊模式,其默認模板不包含身份管理相關模塊,更適合用于搭建普通的業務微服務。
以產品管理服務為例,我們在解決方案目錄中找到service目錄,在其中創建productmanager目錄,切換至該目錄并啟動cmd命令行。使用以下命令創建產品管理服務:
abp new Demo.ProductManager -t module --no-ui其中
????-t module表示模塊模式
????--no-ui表示不使用UI界面
在ABP vNext框架Module模式下一直存在一個問題,創建時無法和Application一樣使用-dbms參數設置數據庫類型,而是使用默認的SQL Server數據庫類型,這里我們的項目采用MySQL數據庫,需要手動修改為MySQL,具體方法見下一章節。
因為我們身份認證服務采用統一的服務,所以我們在生成的模板中找到host目錄下的ProductManager.IdentityServer項目文件夾并刪除,數據庫我們不使用MongoDB,所以可以將src目錄下的ProductManager.MongoDB項目文件夾和test目錄下的ProductManager.MongoDB.Tests項目文件夾刪除。之后我們可以刪除該項目根目錄下database文件夾和除Demo.ProductManager.sln、common.props以外的所有文件,如果不需要對該項目進行單元測試,也可刪除test文件夾。
清理后,跳轉到總解決方案所在目錄,使用解決方案構建工具將產品管理服務所有項目添加到總解決方案,添加后效果如下:
2
切換為Mysql數據庫
將Module模式項目從SQL Server數據庫更改為MySQL數據庫步驟如下:
1. 找到ProductManager.HttpApi.Host項目移除其Nuget引用中的Volo.Abp.EntityFrameworkCore.SqlServer,然后添加Nuget引用Volo.Abp.EntityFrameworkCore.MySQL,注意版本號和主項目ABP框架版本一致。
2. 找到ProductManager.HttpApi.Host項目中的模塊類ProductManagerHttpApiHostModule,將其特性DependsOn特性中引用的?typeof(AbpEntityFrameworkCoreSqlServerModule)?更改為?typeof(AbpEntityFrameworkCoreMySQLModule)?并將其命名空間引用?using?Volo.Abp.EntityFrameworkCore.SqlServer;?改為?using?Volo.Abp.EntityFrameworkCore.MySQL;?。將ConfigureServices方法的
Configure<AbpDbContextOptions>(options =>?{ options.UseSqlServer(); });?改為?Configure<AbpDbContextOptions>(options =>?{ options.UseMySQL(); });
3. 找到ProductManager.HttpApi.Host項目中的ProductManagerHttpApiHostMigrationsDbContextFactory類,將其方法CreateDbContext中的?var?builder =?new?DbContextOptionsBuilder<ProductManagerHttpApiHostMigrationsDbContext>() .UseSqlServer(configuration.GetConnectionString("ProductManager"));?改為以下代碼(注意我的MySQL版本為5.7,具體版本號請依據個人情況修改):
var builder = new DbContextOptionsBuilder<ProductManagerHttpApiHostMigrationsDbContext>().UseMySql(configuration.GetConnectionString("ProductManager"),ServerVersion.Parse("5.7.28-mysql"));4. 修改Demo.ProductManager.HttpApi.Host項目的appsettings.json配置文件,和Application模式不同,我們會發現Module模式下ABP vNext框架提供的項目模板ConnectionStrings項會包含Default和ProductManager兩個配置項。其中Default為ABP框架基礎配置信息的數據庫,身份管理服務已包含其所需的所有數據,所以我們將Default配置為和身份管理中心相同的數據庫鏈接。ProductManger也就是和當前項目相同的數據庫配置項,所指向的數據庫為對當前模塊領域實體持久化的數據庫,需要在當前項目中配置和創建。
5. 進入Demo.ProductManager.HttpApi.Host項目所在目錄,執行數據遷移命令?dotnet-ef database update?,執行成功后查看數據庫,發現已創建模塊數據庫,且僅包含__EFMigrationsHistory表,則數據庫鏈接成功。
3
初始化運行
在Demo.ProductManager.Application、Demo.ProductManager.Application.Contracts、Demo.ProductManager.HttpApi三個項目中分別找到Samples文件夾并刪除,這是ABP vNext提供的樣例API,沒有實際用途。
設置端口號為5010并允許IP地址訪問,方式為在Demo.ProductManager.HttpApi.Host項目配置文件appsettings.json中添加配置項:?"urls":?"http://*:5010"?
上一章節我們已經配置了數據庫鏈接字符串,我們繼續編輯Demo.ProductManager.HttpApi.Host項目配置文件appsettings.json,設置Redis鏈接字符串。
啟動Demo.ProductManager.HttpApi.Host項目并訪問http://localhost:5010/swagger/index.html,可以正常顯示Swagger頁面,即啟動成功。
4
產品管理API
01
領域層
在Demo.ProductManager.Domain項目中添加Products文件夾(產品領域)并創建Product類(產品聚合根)代碼如下:
using System; using Volo.Abp.Domain.Entities;namespace Demo.ProductManager.Products;/// <summary> /// 產品 /// </summary> public class Product : AggregateRoot<Guid> {/// <summary>/// 名稱/// </summary>public string Name { get; set; }/// <summary>/// 價格/// </summary>public float Price { get; set; } }02
數據庫創建
在Demo.ProductManager.EntityFrameworkCore項目中找到IProductManagerDbContext接口和ProductManagerDbContext類,分別添加?DbSet<Product> Products {?get;?set; }?和?public?DbSet<Product> Products {?get;?set; }?屬性并添加相應引用。
在Demo.ProductManager.EntityFrameworkCore項目中找到ProductManagerDbContextModelCreatingExtensions類中的ConfigureProductManager方法內添加以下內容:
builder.Entity<Product>(b => {b.ToTable(ProductManagerDbProperties.DbTablePrefix+ "Products", ProductManagerDbProperties.DbSchema);b.ConfigureByConvention(); });這里使用實體類默認設置,如果需要進行自定義修改,可自行編輯實體配置。
在Demo.ProductManager.HttpApi.Host項目所在目錄中執行創建數據遷移語句:
dotnet-ef migrations Add BuildProduct創建成功后執行數據遷移:
dotnet-ef database update執行成功后,我們可以在ProductManager模塊數據庫中看到已新增數據庫表Product,此表中除主鍵ID和我們自己定義的兩個字段以外,如果Product繼承自AggregateRoot,則會包含ExtraProperties和ConcurrencyStamp兩個字段,分別為擴展屬性和并發戳。若繼承自Entity則默認不會包含這兩個字段。
03
應用層
為方便演示,本實例采用CrudAppService,對Product提供增刪改查接口,具體實現方式如下:
在Demo.ProductManager.Application.Contracts項目中創建Products文件夾并在其中創建Dto文件夾。在Dto文件夾中存放產品管理的數據傳輸對象,這里增刪改查接口統一使用ProductDto,代碼如下:
using System; using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Entities;namespace Demo.ProductManager.Products.Dto;/// <summary> /// 產品DTO /// </summary> public class ProductDto : EntityDto<Guid>, IHasConcurrencyStamp {/// <summary>/// 名稱/// </summary>public string Name { get; set; }/// <summary>/// 價格/// </summary>public float Price { get; set; }/// <summary>/// 并發戳/// </summary>public string ConcurrencyStamp { get; set; } }這里因為我們使用聚合根,修改數據時需要提供并發戳ConcurrencyStamp,但EntityDto中并未提供該字段,所以需繼承IHasConcurrencyStamp接口。
在Demo.ProductManager.Application.Contracts項目Products文件夾下添加產品管理應用服務接口IProductAppService如下:
using System; using Demo.ProductManager.Products.Dto; using Volo.Abp.Application.Services;namespace Demo.ProductManager.Products;/// <summary> /// 產品管理應用服務接口 /// </summary> public interface IProductAppService : ICrudAppService<ProductDto, Guid> {}在Demo.ProductManager.Application項目中添加Products文件夾,添加應用服務類ProductAppService如下:
using System; using Demo.ProductManager.Products.Dto; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories;namespace Demo.ProductManager.Products;/// <summary> /// 產品管理應用服務 /// </summary> public class ProductAppService:CrudAppService<Product,ProductDto,Guid>,IProductAppService {public ProductAppService(IRepository<Product, Guid> repository) : base(repository){} }為方便多個領域下AutoMapper映射關系的管理,我在每個領域單獨創建一個靜態類,以擴展方法的方式編寫當前領域的對象映射關系。例如在當前Products領域中,在Demo.ProductManager.Application項目中Products文件夾下添加靜態類ProductAutoMapperProfile如下:
using Demo.ProductManager.Products.Dto;namespace Demo.ProductManager.Products;public static class ProductAutoMapperProfile {public static void CreatProductMapper(this ProductManagerApplicationAutoMapperProfile profile){profile.CreateMap<Product, ProductDto>();profile.CreateMap<ProductDto, Product>();} }之后,就可以在ProductManagerApplicationAutoMapperProfile類的ProductManagerApplicationAutoMapperProfile方法中增加以下代碼:
this.CreatProductMapper();通常情況,DTO和實體的字段并非完全一一對應,我們需要再映射過程中忽略映射關系的校驗,具體方法為將ProductManagerApplicationModule類中ConfigureServices方法下??Configure<AbpAutoMapperOptions>(options =>?{ options.AddMaps<ProductManagerApplicationModule>(validate:?true); });?這一句validate參數值改為false
04
其他處理
ABP vNext框架Module模式模板默認未開啟動態WebAPI,需要我們手動啟用動態WebAPI,具體方式為在Demo.ProductManager.HttpApi.Host項目的ProductManagerHttpApiHostModule類ConfigureServices方法中添加以下代碼:
Configure<AbpAspNetCoreMvcOptions>(options =>{ options .ConventionalControllers .Create(typeof(ProductManagerApplicationModule).Assembly); });
通常情況,我們使用的倉儲為ABP vNext框架提供的默認倉儲實現,我們需要一次性添加所有默認倉儲,具體方法為在Demo.ProductManager.EntityFrameworkCore項目中ProductManagerEntityFrameworkCoreModule類的ConfigureServices方法中,找到?context.Services.AddAbpDbContext<ProductManagerDbContext>(……?,在其中添加options.AddDefaultRepositories();修改為:
context.Services.AddAbpDbContext<ProductManagerDbContext>(options =>{ ? ?/*?Add custom repositories here. Example: ? ? * options.AddRepository<Question, EfCoreQuestionRepository>(); ? ?*/?? ?options.AddDefaultRepositories(); });
完成以上修改后,運行Demo.ProductManager.HttpApi.Host項目并打開http://localhost:5010/swagger/index.html,可顯示Swagger頁面并包含,Product相關增刪改查接口,可通過Swagger頁面完成測試。
end
更多精彩
關注我獲得
總結
以上是生活随笔為你收集整理的ABP vNext微服务架构详细教程——基础服务层的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET6之MiniAPI(十):基于策
- 下一篇: 如何实现二次抛异常时保存第一次异常的详细