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