从壹开始前后端分离【 .NET Core2.2 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储+服务+抽象接口模式...
前言
1、@LearningCoding?小伙伴關(guān)于用Sqlsugar在mysql數(shù)據(jù)庫上的研究成果:
sqlsugarcore支持mysql等數(shù)據(jù)庫,在DbContext里面只需要設(shè)置dbtype為mysql即可,但是mysql8.0以上是個坑,會出現(xiàn)caching_sha2_password的錯誤,是因為root的密碼類型問題,改起來挺麻煩的,所以建議使用mysql的時候安裝5.6版本的即可,其他代碼不需要改動。
?
書接上文:前幾回文章中,我們花了三天的時間簡單了解了下接口文檔Swagger框架,已經(jīng)完全解放了我們的以前的Word說明文檔,并且可以在線進(jìn)行調(diào)試,而且當(dāng)項目開始之中,我們可以定義一些空的接口,或者可以返回假數(shù)據(jù),這樣真正達(dá)到了前后端不等待的缺陷,還是很不錯的,當(dāng)然,這離我說的前后端分離還是相差甚遠(yuǎn),今天呢,我們就簡單搭建下我們的項目架構(gòu)。
本項目是我自己的一個真實項目,數(shù)據(jù)都是真實的,之前搭建過一個MVC + EF Code First的項目,本項目就是基于這個了,前一段時間我已經(jīng)搭建起來了,是這樣的,本系列教程會重新開始。
?
零、完成圖中的粉色部分
?
?
?
先簡單解釋下各層之間的調(diào)用關(guān)系:
?
除了項目對外暴露的是 Api 展示層,和核心的實體 Model 層外,
?
倉儲模塊(作為一個數(shù)據(jù)庫管理員,直接操作數(shù)據(jù)庫,實體模型):
BaseRepository(基類倉儲) 繼承實現(xiàn)了 接口IBaseRepository,這里放公共的方法,
AdvertisementRepostitory 繼承?BaseRepository<Advertisement>, IAdvertisementRepository
?
Service模塊(處理業(yè)務(wù)邏輯,可以直接使用ViewModel視圖模型):
BaseService 調(diào)用 BaseRepository,同時繼承 IBaseService
AdvertisementServices??繼承???BaseServices<Advertisement>, IAdvertisementServices
?
?
一、創(chuàng)建實體Model數(shù)據(jù)層
其中,Models文件夾中,存放的是整個項目的數(shù)據(jù)庫表實體類,這里是手動創(chuàng)建的,當(dāng)然也可以自動創(chuàng)建,在以后的文章中我會提到,用到的是SqlSugar的T4創(chuàng)建,這里先買一個伏筆。
提示:這個伏筆已經(jīng)完成,地址《?三十二║ 四種方法快速實現(xiàn)項目的半自動化搭建》
然后,VeiwModels文件夾,是存放的DTO實體類,在開發(fā)中,一般接口需要接收數(shù)據(jù),返回數(shù)據(jù),我之前都是這么紅果果的使用的,后來發(fā)現(xiàn)弊端很大,不僅把重要信息暴露出去(比如手機號等),還對數(shù)據(jù)造成冗余(比如我需要接收用戶的生日,還需要具體的年、月、日這就是三個字段,當(dāng)然您也可以手動拆開,這只是一個栗子,所以不能直接用數(shù)據(jù)庫實體類接收),就用到了DTO類的轉(zhuǎn)換,但是頻繁的轉(zhuǎn)換又會麻煩,別慌,以后的文章中,我們會引用AutoMapper來自動轉(zhuǎn)換,這里再買一個伏筆。
提示:這個伏筆已經(jīng)完成,地址《十三 || DTOs 對象映射使用》
最后的是MessageModel和TableModel,大家也基本一看就能明白,因為在前端接口中,需要固定的格式,以及操作,不能把數(shù)據(jù)直接發(fā)出去,會報錯,在以后的Vue開發(fā)中,會提到這個,這里又買了一個伏筆。?如下:
/// <summary>/// 通用返回信息類/// </summary>public class MessageModel<T>{/// <summary>/// 操作是否成功/// </summary>public bool Success { get; set; }/// <summary>/// 返回信息/// </summary>public string Msg { get; set; }/// <summary>/// 返回數(shù)據(jù)集合/// </summary>public List<T> Data { get; set; }}整個項目運行,沒錯,繼續(xù)創(chuàng)建下一層。
?
二、設(shè)計倉儲接口與其實現(xiàn)類
創(chuàng)建Blog.Core.IRepository和 Blog.Core.Repository 倉儲層:
這里簡單說下倉儲層:repository就是一個管理數(shù)據(jù)持久層的,它負(fù)責(zé)數(shù)據(jù)的CRUD(Create, Read, Update, Delete) service layer是業(yè)務(wù)邏輯層,它常常需要訪問repository層。有網(wǎng)友這么說:Repository(倉儲):協(xié)調(diào)領(lǐng)域和數(shù)據(jù)映射層,利用類似與集合的接口來訪問領(lǐng)域?qū)ο蟆epository 是一個獨立的層,介于領(lǐng)域?qū)优c數(shù)據(jù)映射層(數(shù)據(jù)訪問層)之間。它的存在讓領(lǐng)域?qū)痈杏X不到數(shù)據(jù)訪問層的存在,它提供一個類似集合的接口提供給領(lǐng)域?qū)舆M(jìn)行領(lǐng)域?qū)ο蟮脑L問。Repository 是倉庫管理員,領(lǐng)域?qū)有枰裁礀|西只需告訴倉庫管理員,由倉庫管理員把東西拿給它,并不需要知道東西實際放在哪。
?
? 我們定義了IRepository層,提供了所有的操作接口,今天搭建框架,我簡單地寫一個實例,明天我們將把所有的方法嵌套進(jìn)去。
在 IAdvertisementRepository.cs 中,添加一個求和接口
public interface IAdvertisementRepository{int Sum(int i, int j);}
然后再在?AdvertisementRepository.cs 中去實現(xiàn)該接口,記得要添加引用,這個應(yīng)該都會,就不細(xì)說了。
public class AdvertisementRepository : IAdvertisementRepository{public int Sum(int i, int j){return i + j;}}?
?運行項目,一起正常,繼續(xù)往下。
三、設(shè)計服務(wù)接口與其實現(xiàn)類
創(chuàng)建 Blog.Core.IServices 和 Blog.Core.Services 業(yè)務(wù)邏輯層,就是和我們平時使用的三層架構(gòu)中的BLL層很相似:
?
Service層只負(fù)責(zé)將Repository倉儲層的數(shù)據(jù)進(jìn)行調(diào)用,至于如何是與數(shù)據(jù)庫交互的,它不去管,這樣就可以達(dá)到一定程度上的解耦,假如以后數(shù)據(jù)庫要換,比如MySql,那Service層就完全不需要修改即可,至于真正意義的解耦,還是得靠依賴注入,這下一節(jié)我們會講到。
這里在?IAdvertisementServices 中添加接口
namespace Blog.Core.IServices {public interface IAdvertisementServices {int Sum(int i, int j);} }
然后再在 AdvertisementServices 中去實現(xiàn)該接口
public class AdvertisementServices : IAdvertisementServices{IAdvertisementRepository dal = new AdvertisementRepository();public int Sum(int i, int j){return dal.Sum(i, j);}}
注意!這里是引入了三個命名空間
using Blog.Core.IRepository;
using Blog.Core.IServices;?
using Blog.Core.Repository;
?
四、創(chuàng)建 Controller 接口調(diào)用
?
?
? 將系統(tǒng)默認(rèn)的ValueController刪除,手動添加一個BlogController控制器,可以選擇一個空的,也可以選擇一個帶有默認(rèn)讀寫實例的。如下:
[Produces("application/json")][Route("api/Blog")][Authorize(Policy ="Admin")]public class BlogController : Controller{// GET: api/Blog [HttpGet]public IEnumerable<string> Get(){return new string[] { "value1", "value2" };}// GET: api/Blog/5[HttpGet("{id}", Name = "Get")]public string Get(int id){return "value";}// POST: api/Blog [HttpPost]public void Post([FromBody]string value){}// PUT: api/Blog/5[HttpPut("{id}")]public void Put(int id, [FromBody]string value){}// DELETE: api/ApiWithActions/5[HttpDelete("{id}")]public void Delete(int id){}}
接下來,在應(yīng)用層添加服務(wù)層的引用
using Blog.Core.IServices;
using Blog.Core.Services;
? 然后,改寫Get方法
·······// GET: api/Blog/// <summary>/// Sum接口/// </summary>/// <param name="i">參數(shù)i</param>/// <param name="j">參數(shù)j</param>/// <returns></returns> [HttpGet]public int Get(int i,int j){IAdvertisementServices advertisementServices = new AdvertisementServices();return advertisementServices.Sum(i,j);}F5 運行項目,調(diào)試如下:
天呀!出錯辣!別慌,還記得昨天咱們加的權(quán)限么,嗯!就是那里,手動模擬登陸,獲取Token,注入,不會的可以看上一篇,然后再執(zhí)行,結(jié)果:
?
?
?
?
五、結(jié)語
好啦,今天的工作暫時到這里了,你可以看到整體項目的搭建,結(jié)構(gòu),如何引用,如何測試等,當(dāng)然,這里還是有很多小問題,比如:
·如果每個倉儲都需要這么寫,至少是四遍,會不會太麻煩;
·每次Controller接口調(diào)用,需要引入很多命名空間
·等等等等
這些問題,下一節(jié)我們都會帶大家一起去慢慢解決!
?
六、Github && Gitee
?
https://github.com/anjoy8/Blog.Core.git
https://gitee.com/laozhangIsPhi/Blog.Core
?
轉(zhuǎn)載于:https://www.cnblogs.com/laozhang-is-phi/p/9516890.html
總結(jié)
以上是生活随笔為你收集整理的从壹开始前后端分离【 .NET Core2.2 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储+服务+抽象接口模式...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity持久化存储之PlayerPre
- 下一篇: vue中全局引入bootstrap.cs