基於.NET6的簡單三層管理系統
- 2022 年 9 月 16 日
- 筆記
- 0-項目, ASP.NET Core 6.0, 完整項目
前言
筆者前段時間搬磚的時候,有了一個偷懶的想法:如果開發的時候,簡單的CURD可以由代碼生成器完成,相應的實體、服務都不需要再做額外的註冊,這樣開發人員可以省了很多事。
於是就開了這個項目,期望實現這樣的能力:業務人員只需關注實體的構建,業務服務的編寫,以及路由的配置。
讓業務的開發,變成簡單的三步走:創建實體 >> 業務開發 >> 路由配置。
目前項目構思的絕大部分能力已完成(代碼生成器、定時任務還未實現),現將項目發佈,希望能對搬磚的大傢伙有所幫助。
項目概述
前後端分離,使用 JWT 認證。
後端:基於 .NET6 和 EF Core,集成常用組件,採用傳統三層結構。
前端:基於 小諾1.8 做適配,主技術棧:Vue2.6.x、Ant-Design-Vue
體驗地址
管理員:superAdmin 密碼:123456
普通用戶:user 密碼:123456
快速開始
請參考項目文檔:使用手冊
參考項目
註:排名不分先後。
感謝這些優秀的開源項目!
基本設計思路
-
依賴於抽象
依賴倒置原則,控制反轉(IoC)
-
切面編程(AOP)
權限、日誌、異常等通過過濾器(Filter)或中間件(Middleware)等實現,集中編程
-
可配置
-
自動註冊
自動註冊實體(Entity)、自動註冊服務類(Service)等
項目結構
項目結構構思
主要分為三層:Interface表現層、Services服務層、Repository倉儲層
Interface:Host依賴所有層,完成程序配置(如:Program.cs 中DI容器注入服務,中間件管道配置等);Web API 配置路由,提供 API 接口,如果程序以後有遷移、或替換前端的情況,也可以在這裡做一層適配器(註:API只是一種表現形式,也可以為MVC)
Services:所有的業務都在這一層。從倉儲中讀取數據模型(Models),進行業務操作,返回DTO(Data transfer objects)給表現層。
Repository:數據庫訪問。
通用的模塊:Model、Common、Framework
Models:包含所有數據模型,如 Entity(對象數據庫的數據表)、CacheItem緩存對象、EventModel事件模型等。
Common:集成常用組件,根據項目需要做相應配置;提供基礎服務,如CurrentUser訪問當前用戶信息;提供靜態幫助類,所有無狀態的函數都歸入此類,如GuidHelper.Next()
產生連續 Guid。
Framework:框架,比如引用ABP或Furion等框架,甚至是自己項目一些通用的能力,可以到處用的。
實際項目結構
實際上,把 IServices 和 IRepository 此類接口層幹掉了。
Models 則歸入了對應的使用者裏面,Framework 也沒有。
Common # 基礎設施:集成常用組件;提供基礎服務;提供靜態幫助類
Repository # 倉儲層:數據庫訪問,數據庫遷移
Services # 服務層:業務實現
WebApi # 表現層:完成程序配置;配置路由,提供API接口
目錄結構如下,更詳細的結構,請查看文檔。
├─config # 一些配置文件,如:redis 的配置文件
├─doc # 項目文檔
├─web # 前端
├─webapi # 後端
├─Simple.Common # 基礎設施
├─Simple.Repository # 倉儲層
├─Simple.Services # 服務層
└─Simple.WebApi # 表現層
業務能力
- 組織架構
- 組織機構(organization)
- 崗位(position)
- 用戶(user)
- 權限管理
- 應用(application)
- 菜單(menu)
- 角色(role)
- 開發管理
- 數據字典(dictionary、dictionaryItem)
- 日誌管理
- 操作日誌(log operating)
- 異常日誌(log exception)
系統能力
- 認證:集成Cookies、JWT;默認啟用 JWT
- 授權:基於策略(Policy)的授權
- ORM:EF Core 的 Code First 模式
- 依賴注入:默認 DI 容器,實現自動注入
- 緩存:IDistributedCache,默認注入 Memory Cache,可替換 Redis
- 日誌:NLog
- 事件總線:默認啟用 BackgroupService,基於Channel 實現的單機版發佈訂閱;可替換為 Redis 的發佈訂閱(可用於分佈式);也可替換為 RabbitMQ 的發佈訂閱(可用於分佈式)
- 定時任務:Quartz
- 數據驗證:模型驗證(Model validation)
- 對象映射:AutoMapper
項目亮點
一些Q&A
為什麼把 IServices 這些接口層給幹掉了,僅留下實現層?
答:一般項目中會如有 IRepository 和 IServices 這些個抽象層,主要是為了控制反轉(IoC),實現項目各層之間解耦,最終目的就是為了「高內聚,低耦合」。
筆者認為,對於單體項目來說,做到高內聚即可,再追求完全的低耦合,會增加成本和困擾(舉個簡單的栗子:項目初期,業務大改是常有的事,改服務類的接口的事並不少見。除非說業務主體明確,需要修改的,並不是業務的接口,而是業務的具體實現)。
最後是這個項目,本就是為了追求最簡三層單體。
為什麼不對倉儲額外封裝一層?
答:簡單的項目基本上是單數據庫的,且 EF Core 已經實現了工作單元和倉儲模式,可以不用再封裝一層。
當然,筆者還是建議跟ABP框架那樣再封裝一層倉儲,可以避免一些後續的開發運維問題(比如:系統遷移、重構等)。
源碼
Gitee://gitee.com/lisheng741/simpleapp
Github://github.com/lisheng741/SimpleApp