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

4.1. 領域層

在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; }
}

4.2. 數據庫創建

在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則默認不會包含這兩個字段。

4.3. 應用層

為方便演示,本實例采用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

4.4其他處理

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頁面完成測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM