.NetCore(.Net5)快速開發框架一:快速開發


上一篇我們完成了項目首次啟動的初始化工作,這一篇我們來看看使用AdmBoots實現一個業務的具體實踐。

系列教程

01.NetCore(.Net5)快速開發框架一:前言
02.NetCore(.Net5)快速開發框架二:快速開發
03.NetCore(.Net5)快速開發框架三:WebAPI性能監控-MiniProfiler與Swagger集成
04.NetCore(.Net5)快速開發框架四:實現審計日志
...

創建Model

在Domain層下創建模型 Test.cs 然后使用Code First將表生成到數據庫。或者你也可以使用DB First 現在數據庫建表,然后通過命令反向生成Model。

[Table("Test")] public class Test : AuditEntity { [Required, MaxLength(EntityDefault.FieldsLength50)] public string Name { get; set; } public int Age { get; set; } } 

Test類繼承了抽象類AuditEntity,AuditEntity具有以下屬性

 public class AuditEntity : CreationEntity<int> { public int? ModifierId { get; set; } [MaxLength(EntityDefault.LongNameLength)] public string ModifierName { get; set; } public DateTime? ModifyTime { get; set; } } public class CreationEntity : CreationEntity<int> { } public class CreationEntity<TKey> : Entity<TKey> { public TKey CreatorId { get; set; } [MaxLength(EntityDefault.LongNameLength)] public string CreatorName { get; set; } public virtual DateTime? CreateTime { get; set; } } [Serializable] public abstract class Entity<TPrimaryKey> : IEntity<TPrimaryKey> { [Key] public virtual TPrimaryKey Id { get; set; } public virtual bool IsTransient() { if (EqualityComparer<TPrimaryKey>.Default.Equals(Id, default(TPrimaryKey))) { return true; } if (typeof(TPrimaryKey) == typeof(int)) { return Convert.ToInt32(Id) <= 0; } if (typeof(TPrimaryKey) == typeof(long)) { return Convert.ToInt64(Id) <= 0; } return false; } } 

想必大家已經看出來繼承AuditEntity的作用了,它是一個審計接口,繼承這個類,可以在我們對Test進行增加,修改的時候,數據庫中AuditEntity對應字段會自動賦值,無需我們在邏輯層手動編碼。這對我們開發業務時,會大大減少重復編碼工作量。

Model編寫完后,別忘了在AdmDbContext中添加DbSet

    public class AdmDbContext : DbContext { //... public virtual DbSet<Test> Tests { get; set; } //... } 

代碼生成

框架實現了代碼生成器,可以生成CURD框架代碼,減少代碼的重復編寫。目前實體類生成還只限Mysql數據庫,可以根據自己的數據庫自行擴展。

下面我們來看看具體怎么使用

  1. 啟動項目,在Swagger頁面的CodeGenerator 控制器下做如下操作

返回我們的項目,可以看到在Controller下,Application層都創建好了文件夾及代碼,我們向里面添加邏輯就可以了

創建Service

一些相關解釋

Service 在應用服務層也就是application層。應用服務用於將領域(業務)邏輯暴露給展現層。展現層通過傳入DTO(數據傳輸對象)參數來調用應用服務,而應用服務通過領域對象來執行相應的業務邏輯並且將DTO返回給展現層。

也就是這樣避免了應用服務層和展現層的直接數據交互,而是通過dto實現了數據過濾,這樣就可以較好的避免非法數據的傳入傳出。另外還有實現數據隱藏,方便擴展等好處。

創建應用服務時需要注意:

  1. IxxxService 要實現ITransientDependency接口,繼承此接口可將服務注入到容器。

  2. 繼承AppServiceBase抽象類,該類通過屬性提供了工作單元,AutoMapper,Session對象

  3. AdmBoots中,一個應用服務方法默認是一個工作單元(Unit of Work),AdmBoots自動進行事務管理。可通過在方法上添加特性[UnitOfWork(IsDisabled = true)] 關閉工作單元。(是不是和ABP這里很像☺)

public class TestService : AppServiceBase, ITestService { //... } public interface ITestService :ITransientDependency { //... } 

Dto 數據傳輸對象

建議命名 input/ouput 對象類似於 MethodNameInput/MethodNameOutput,對於每個應用服務方法都需要將 Input 和 Output 進行分開定義。甚至你的方法只接收或者返回一個值,也最好創建相應的 DTO 類型。 這樣會使代碼有更好的擴展性。

怎么將Test實體類轉換為dto,這時就需要使用AutoMapper 進行映射了。

 public Task AddOrUpdateTest(int? id, AddOrUpdateTestInput input) { var testEntity = ObjectMapper.Map<Test>(input); //... } public class AutoMapProfile : Profile { /// <summary> /// 配置構造函數,用來創建關系映射 /// </summary> public AutoMapProfile() { // CreateMap<Test, GetTestOutput>(); } } 

注意,根據DDD領域驅動設計,業務比較復雜時(多領域),業務邏輯的實現應該在Domain層實現

應用層要盡量簡單,主要用於協調領域模型與其他應用組件的工作(並不處理業務邏輯)。相對於領域層,應用層應該是很薄的一層。它只是協調領域層對象執行實際的工作。

領域層主要負責表達業務概念,業務狀態信息和業務規則。

Domain層是整個系統的核心層,幾乎全部的業務邏輯會在該層實現。

API策略授權

API授權可以參照框架中RoleController,主要分為以下幾個部分

  1. 在RoleController 上添加特性 [Authorize(AdmConsts.POLICY)]
[Authorize(AdmConsts.POLICY)]
public class RoleController : ControllerBase { //... } 
  1. Action上添加特性 [AdmAuthorizeFilter("Role:Add")] 其中"Role:Add"為該資源的標識,這里先記住這個標識,后面授權會用到。也可以不添加AdmAuthorizeFilter特性,那么資源標識默認為"ControllerName:ActionName", 如"Role:AddRole"為AddRole這個Action的默認資源標識
[HttpPost]
//自定義資源標識 [AdmAuthorizeFilter("Role:Add")] public async Task<IActionResult> AddRole([FromBody]AddOrUpdateRoleInput input) { await _roleService.AddOrUpdateRole(null, input); return Ok(ResponseBody.From("保存成功")); } 
  1. 如果在標有[Authorize(AdmConsts.POLICY)]策略授權的Controller中某個Action我們不想設置權限,我們可以在Action上使用特性[AllowAnonymous]
[HttpGet("transferRoles")] [AllowAnonymous] public IActionResult GetTransferRoles() { var roles = _roleService.GetTransferRoles(); return Ok(ResponseBody.From(roles)); } 
  1. 將API資源分配個某個角色
    一般情況下,一個API地址為前端一個具體操作,比如一個按鈕的動作。
    這里我們運行前端AdmBoots-Client,通過菜單管理及角色管理來進行API授權。
    登陸賬號:admin 密碼:a123456

    a.菜單管理 中添加按鈕權限信息

    b.角色管理 中會看到我們剛才添加的按鈕信息,勾選保存。這樣擁有該角色的用戶就擁有了此操作的權限。

    c.前端使用AuthWrapper組件嵌套權限按鈕,可以實現對沒有權限操作的按鈕進行隱藏

    //authorized: 菜單按鈕的code值 //pageCode: 按鈕所在菜單的路由 <AuthWrapper authorized="add" pageCode="juesgl"> <Button type="primary" icon={<PlusOutlined/>} onClick={this.onAdd}> 新增 </Button> </AuthWrapper> 

至此,AdmBoots實踐內容就介紹完了,可能介紹的並不完全,比如自定義倉儲,分頁操作,數據返回格式,分步事務提交等,還有很多細節沒有說明,大家自行探索吧。有什么問題歡迎留言或進群詢問。

源碼地址

后端:https://github.com/xuke353/AdmBoots

前端:https://github.com/xuke353/AdmBoots-Client


免責聲明!

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



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