從本篇文章開始,我們將用兩篇內容詳細介紹幣種服務的實現。幣種服務本身結構較為簡單,核心功能包括內置幣種的初始化、幣種匯率的同步以及匯率的查詢。在本篇中,我們將重點講解如何實現內置幣種的初始化功能,為后續的服務打下基礎。而在下一篇文章中,我們將繼續深入,講解幣種匯率的同步機制以及如何進行匯率的查詢操作。
一、基礎搭建
在基礎搭建部分,與前面的服務類似,我們需要創建一個新的微服務項目,并添加必要的依賴項,以及添加數據庫上下文類和幣種實體類。以下是我們需要完成的步驟:
我們在SporeAccounting
解決方案下創建一個名為SP.CurrencyService
的 Web API 項目。接著,我們需要添加以下 NuGet 包:AutoMapper
、Pomelo.EntityFrameworkCore.MySql
、Microsoft.EntityFrameworkCore.Design
、nacos-sdk-csharp
、nacos-sdk-csharp.Extensions.Configuration
、nacos-sdk-csharp.AspNetCore
。這六個包分別用于自動映射、MySQL 數據庫訪問、Entity Framework Core 設計時支持、Nacos SDK 以及 Nacos 的 ASP.NET Core 擴展,具體使用方法在這里就不詳細講解了,有不清楚的可以參考我其他的專欄,或者在網上搜索相關內容。
接下來,我們創建一個名為Currency
的實體類,表示幣種。這個類包含了幣種名稱和幣種縮寫等屬性。實體類代碼如下:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using SP.Common.Model;namespace SP.CurrencyService.Models.Entity;/// <summary>
/// 幣種
/// </summary>
[Table(name: "Currency")]
public class Currency : BaseModel
{/// <summary>/// 幣種名稱/// </summary>[Column(TypeName = "nvarchar(20)")][Required]public string Name { get; set; }/// <summary>/// 幣種縮寫/// </summary>[Column(TypeName = "nvarchar(10)")][Required]public string Abbreviation { get; set; }
}
然后,我們需要創建一個數據庫上下文類CurrencyServiceDbContext
,它繼承自DbContext
,并包含一個DbSet<Currency>
屬性,用于訪問幣種數據。數據庫上下文代碼如下:
using Microsoft.EntityFrameworkCore;
using SP.Common;
using SP.CurrencyService.Models.Entity;namespace SP.CurrencyService.DB;/// <summary>
/// 幣種服務數據庫上下文
/// </summary>
public class CurrencyServiceDbContext : DbContext
{/// <summary>/// 貨幣/// </summary>public DbSet<Currency> Currencies { get; set; }/// <summary>/// 數據庫連接配置/// </summary>private readonly IConfiguration _dbConfig;/// <summary>/// 構造函數/// </summary>/// <param name="dbConfig"></param>public CurrencyServiceDbContext(IConfiguration dbConfig){_dbConfig = dbConfig;}/// <summary>/// 數據庫連接配置/// </summary>/// <param name="optionsBuilder"></param>protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){var serverVersion = ServerVersion.AutoDetect(_dbConfig.GetConnectionString("MySQLConnection"));optionsBuilder.UseMySql(_dbConfig.GetConnectionString("MySQLConnection"), serverVersion);}
}
下一步,在數據庫上下文CurrencyServiceDbContext
類中,重寫OnModelCreating
方法,在這個方法中我們將調用SeedData
方法初始化內置幣種,這樣當我們在遷移數據庫時就會自動初始化內置幣種。這里我們只初始化常用的幾種幣種,當然你也可以根據實際需求添加更多的幣種。代碼如下:
/// <summary>
/// 模型創建
/// </summary>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{SeedData(modelBuilder);base.OnModelCreating(modelBuilder);
}/// <summary>
/// 種子數據
/// </summary>
/// <param name="modelBuilder"></param>
private void SeedData(ModelBuilder modelBuilder)
{long adminUserId = 7333155174099406848;modelBuilder.Entity<Currency>().HasData(new List<Currency>(){new Currency(){Id = Snow.GetId(),Name = "人民幣",Abbreviation = "CNY",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "美元",Abbreviation = "USD",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "歐元",Abbreviation = "EUR",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "日元",Abbreviation = "JPY",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "英鎊",Abbreviation = "GBP",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "澳門幣",Abbreviation = "MOP",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "港元",Abbreviation = "HKD",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "韓圓",Abbreviation = "KRW",CreateUserId = adminUserId,CreateDateTime = DateTime.Now},new Currency(){Id = Snow.GetId(),Name = "新臺幣",Abbreviation = "TWD",CreateUserId = adminUserId,CreateDateTime = DateTime.Now}});
}
在上面的代碼中,我們使用了Snow.GetId()
方法來生成唯一的 ID,這個方法是我們在前面章節中實現的雪花算法 ID 生成器。我們還設置了創建用戶 ID 和創建時間,這些字段都是從BaseModel
類繼承而來的。
接著,我們還需要配置nacos相關的信息,這里我們不詳細講解,只是簡單看一下如何在appsettings.json
中添加nacos相關的下配置:
{"nacos": {"ServerAddresses": [ "http://14.103.224.141:8848" ],"Namespace": "fa420303-2c1c-4b51-a581-ca7210963549","ServiceName": "SPCurrencyService","GroupName": "DEFAULT_GROUP","ClusterName": "DEFAULT","Username": "SP_ADMIN","Password": "123*asdasd","Weight": 100,"ConfigUseRpc": true,"NamingUseRpc": true,"RegisterEnabled": true,"InstanceEnabled": true,"Ephemeral": true,"GrpcReconnectInterval": 5000,"ConnectionTimeOut": 10000,"Listeners": [{"Optional": false,"DataId":"SP.CurrencyService","Group":"DEFAULT_GROUP"},{"Optional": false,"DataId":"Common","Group":"DEFAULT_GROUP"}]}
}
在這個配置中,我們指定了 Nacos 服務器的地址、命名空間、服務名稱、分組名稱、集群名稱、用戶名和密碼等信息。我們還配置了監聽器,用于監聽配置變更,這些配置將用于 Nacos 的服務注冊和配置管理。
Tip:請根據你自己的 Nacos 服務器地址和命名空間等信息進行相應的修改。如果沒有 Nacos 服務器,可以參考我之前的文章搭建一個 Nacos 服務器,或者使用其他的配置中心。
接下來,在Program.cs
文件中配置 Nacos 的服務注冊和配置管理、數據庫上下文,以及AutoMapper。代碼如下:
// 添加Nacos服務注冊
builder.Services.AddNacosAspNet(builder.Configuration);
// 添加Nacos配置中心
builder.Configuration.AddNacosV2Configuration(builder.Configuration.GetSection("nacos"));
builder.Services.AddNacosV2Naming(builder.Configuration);
// 注冊 DbContext
builder.Services.AddDbContext<CurrencyServiceDbContext>(ServiceLifetime.Scoped);
builder.Services.AddAutoMapper(Assembly.GetExecutingAssembly());
最后,我們開始遷移數據庫,在命令行中執行以下命令:
dotnet ef migrations add InitialCreate --context CurrencyServiceDbContext
dotnet ef database update --context CurrencyServiceDbContext
這將創建一個名為InitialCreate
的遷移,并將其應用到數據庫中。執行完畢后,我們就完成了幣種服務的基礎搭建,并且初始化了內置的幣種數據。如下圖:
二、業務實現
在完成了基礎搭建之后,就要實現幣種服務的功能之一 查詢幣種 。在Service文件夾中新建接口文件ICurrencyServer
,該接口中只有一個方法List<CurrencyResponse> Query()
用于查詢幣種列表。接口代碼如下:
using SP.CurrencyService.Models.Entity;
using SP.CurrencyService.Models.Response;namespace SP.CurrencyService.Service;/// <summary>
/// 貨幣服務
/// </summary>
public interface ICurrencyServer
{/// <summary>/// 查詢所有貨幣/// </summary>/// <returns>返回貨幣列表</returns>List<CurrencyResponse> Query();
}
接著,我們在Impl文件夾中新建實現類CurrencyServerImpl
,實現ICurrencyServer
接口。代碼如下:
using AutoMapper;
using SP.CurrencyService.DB;
using SP.CurrencyService.Models.Entity;
using SP.CurrencyService.Models.Response;namespace SP.CurrencyService.Service.Impl;/// <summary>
/// 貨幣服務實現
/// </summary>
public class CurrencyServerImpl : ICurrencyServer
{private readonly CurrencyServiceDbContext _dbContext;private readonly IMapper _mapper;public CurrencyServerImpl(CurrencyServiceDbContext dbContext, IMapper mapper){_dbContext = dbContext;_mapper = mapper;}/// <summary>/// 查詢所有貨幣/// </summary>/// <returns>返回貨幣列表</returns>public List<CurrencyResponse> Query(){List<Currency> crCurrencies = _dbContext.Currencies.ToList();List<CurrencyResponse> currencyResponses = _mapper.Map<List<CurrencyResponse>>(crCurrencies);return currencyResponses;}
}
在上面的代碼中,我們使用了AutoMapper
來將Currency
實體類轉換為CurrencyResponse
響應類。這樣可以簡化數據傳輸對象的轉換過程,提高代碼的可讀性和可維護性。
接著,在Controller文件夾下新建CurrencyController
控制器類,這個控制器只包含一個Web API接口,用于查詢全部幣種。代碼如下:
using Microsoft.AspNetCore.Mvc;
using SP.CurrencyService.Models.Response;
using SP.CurrencyService.Service;namespace SP.CurrencyService.Controllers;/// <summary>
/// 幣種控制器
/// </summary>
[Route("/api/currency")]
[ApiController]
public class CurrencyController : ControllerBase
{private readonly ICurrencyServer _currencyServer;public CurrencyController(ICurrencyServer currencyServer){_currencyServer = currencyServer;}/// <summary>/// 查詢所有幣種/// </summary>/// <returns>返回幣種列表</returns>[HttpGet("query")]public ActionResult<List<CurrencyResponse>> Query(){List<CurrencyResponse> currencies = _currencyServer.Query();return Ok(currencies);}
}
上面的代碼中,通過依賴注入的方式引入了ICurrencyServer
接口,在Query
Action 方法中我們調用了它的Query
方法查詢全部幣種,最后將查詢到的數據返回給API調用方。
最后還需要在Program.cs
文件中將ICurrencyServer
接口及其實現類CurrencyServerImpl
注冊到依賴注入容器中,代碼如下:
builder.Services.AddScoped<ICurrencyServer, CurrencyServerImpl>();
到此為止,幣種服務的內置幣種初始化的全部工作就已完成,當我們運行項目后,就能在Swagger UI界面看到創建的服務了。
三、總結
本篇文章詳細介紹了幣種服務的基礎搭建過程,包括項目結構的創建、依賴包的添加、實體類和數據庫上下文的實現,以及內置幣種的初始化。通過種子數據的方式,確保了服務啟動時能夠自動生成常用幣種數據。同時,介紹了如何實現幣種查詢的業務邏輯,并通過接口和控制器對外提供查詢能力。最后,完成了服務的依賴注入和數據庫遷移,確保服務能夠正常運行。至此,幣種服務的基礎功能已經搭建完成,為后續實現幣種匯率同步和查詢等功能打下了堅實的基礎。下一篇將繼續深入講解幣種匯率相關的實現。