從壹開始先後端分離【 .NET Core2.2/3.0 +Vue2.0 】框架之六 || API項目總體搭建 6.1 倉儲+服務+抽象接口模式

本文3.0版本文章

本文涉及的內容,一樣適用於3.0版本,不用修改。html

 

 

前言

一、@LearningCoding 小夥伴關於用Sqlsugar在mysql數據庫上的研究成果前端

sqlsugarcore支持mysql等數據庫,在DbContext裏面只須要設置dbtype爲mysql便可,可是mysql8.0以上是個坑,會出現caching_sha2_password的錯誤,是由於root的密碼類型問題,改起來挺麻煩的,因此建議使用mysql的時候安裝5.6版本的便可,其餘代碼不須要改動。mysql

 

  書接上文:前幾次文章中,咱們花了三天的時間簡單瞭解了下接口文檔Swagger框架,已經徹底解放了咱們的之前的Word說明文檔,而且能夠在線進行調試,並且當項目開始之中,咱們能夠定義一些空的接口,或者能夠返回假數據,這樣真正達到了先後端不等待的缺陷,仍是很不錯的,固然,這離我說的先後端分離仍是相差甚遠,今天呢,咱們就簡單搭建下咱們的項目架構。git

  本項目是我本身的一個真實項目,數據都是真實的,以前搭建過一個MVC + EF Code First的項目,本項目就是基於這個了,前一段時間我已經搭建起來了,是這樣的,本系列教程會從新開始。github

 

零、完成圖中的粉色部分

 

 

 

先簡單解釋下各層之間的調用關係:sql

 

除了項目對外暴露的是 Api 展現層,和核心的實體 Model 層外,數據庫

 

倉儲模塊(做爲一個數據庫管理員,直接操做數據庫,實體模型):json

BaseRepository(基類倉儲) 繼承實現了 接口IBaseRepository,這裏放公共的方法,
AdvertisementRepostitory 繼承 BaseRepository<Advertisement>, IAdvertisementRepository後端

 

Service模塊(處理業務邏輯,能夠直接使用ViewModel視圖模型):api

BaseService 調用 BaseRepository,同時繼承 IBaseService
AdvertisementServices  繼承   BaseServices<Advertisement>, IAdvertisementServices

 

 2019-08-30:關於倉儲的相關話題

不少人都有一個這樣的想法,倉儲就是Dal層?我這裏簡單說一下二者的區別(我Blog.Core項目可能不是體現的出來,DDD可能更好理解):

一、倉儲是一種模式,能夠單建一層,也能夠放到基礎設施層,

      而Dal是三層架構種的某一層,是一個架構

二、倉儲官方的定義,他是一個管理者,去管理實體對象和ORM映射對象的一個集合,是ORM操做db,

      而Dal就是完徹底全的操做db數據庫了,

      請注意,不要把 Sqlsugar 當成三層中的 sqlhelper,不同!     

三、倉儲更多的是一個聚合,在下一個系列DDD中,咱們說到了一個概念,一個聚合的劃分其實就是一個倉儲。

四、而後咱們進一步細化,一個倉儲 = 一個聚合 = 有一個聚合根 = 一個微服務!

     多個微服務之間交互,就是經過聚合根來的。

 

 

 

1、建立實體Model數據層

  其中,Models文件夾中,存放的是整個項目的數據庫表實體類,這裏是手動建立的,固然也能夠自動建立,在之後的文章中我會提到,用到的是SqlSugar的T4建立,這裏先埋一個伏筆。

提示:這個伏筆已經完成,地址《 三十二║ 四種方法快速實現項目的半自動化搭建

  而後,VeiwModels文件夾,是存放的DTO實體類,在開發中,通常接口須要接收數據,返回數據,我以前都是這麼紅果果的使用的,後來發現弊端很大,不只把重要信息暴露出去(好比手機號等),還對數據形成冗餘(好比我須要接收用戶的生日,還須要具體的年、月、日這就是三個字段,固然您也能夠手動拆開,這只是一個栗子,因此不能直接用數據庫實體類接收),就用到了DTO類的轉換,可是頻繁的轉換又會麻煩,別慌,之後的文章中,咱們會引用AutoMapper來自動轉換,這裏再買一個伏筆。

提示:這個伏筆已經完成,地址《十三 || DTOs 對象映射使用

  最後的是MessageModel和TableModel,你們也基本一看就能明白,由於在前端接口中,須要固定的格式,以及操做,不能把數據直接發出去,會報錯,在之後的Vue開發中,會提到這個,這裏又買了一個伏筆。 以下:

 /// <summary>
    /// 通用返回信息類
    /// </summary>
    public class MessageModel<T>
    {
        /// <summary>
        /// 操做是否成功
        /// </summary>
        public bool Success { get; set; }
        /// <summary>
        /// 返回信息
        /// </summary>
        public string Msg { get; set; }
        /// <summary>
        /// 返回數據集合
        /// </summary>
        public List<T> Data { get; set; }

    }

整個項目運行,沒錯,繼續建立下一層。

 

2、設計倉儲接口與其實現類

建立Blog.Core.IRepository和 Blog.Core.Repository 倉儲層:

  這裏簡單說下倉儲層:repository就是一個管理數據持久層的,它負責數據的CRUD(Create, Read, Update, Delete) service layer是業務邏輯層,它經常須要訪問repository層。有網友這麼說:Repository(倉儲):協調領域和數據映射層,利用相似與集合的接口來訪問領域對象。Repository 是一個獨立的層,介於領域層與數據映射層(數據訪問層)之間。它的存在讓領域層感受不到數據訪問層的存在,它提供一個相似集合的接口提供給領域層進行領域對象的訪問。Repository 是倉庫管理員,領域層須要什麼東西只需告訴倉庫管理員,由倉庫管理員把東西拿給它,並不須要知道東西實際放在哪。

 

   咱們定義了IRepository層,提供了全部的操做接口,今天搭建框架,我簡單地寫一個實例,明天咱們將把全部的方法嵌套進去。

  在 IAdvertisementRepository.cs 中,添加一個求和接口

  

   public interface IAdvertisementRepository
    {
        int Sum(int i, int j);
    }

  而後再在 AdvertisementRepository.cs 中去實現該接口,記得要添加引用,這個應該都會,就不細說了。  

    public class AdvertisementRepository : IAdvertisementRepository
    {
        public int Sum(int i, int j)
        {
            return i + j;
        }
    }

 

   運行項目,一塊兒正常,繼續往下。

3、設計服務接口與其實現類

建立 Blog.Core.IServices 和 Blog.Core.Services 業務邏輯層,就是和咱們平時使用的三層架構中的BLL層很類似:

 

  Service層只負責將Repository倉儲層的數據進行調用,至於如何是與數據庫交互的,它不去管,這樣就能夠達到必定程度上的解耦,假如之後數據庫要換,好比MySql,那Service層就徹底不須要修改便可,至於真正意義的解耦,仍是得靠依賴注入,這下一節咱們會講到。

  這裏在 IAdvertisementServices 中添加接口

  

namespace Blog.Core.IServices
{
    public interface IAdvertisementServices 
    {
        int Sum(int i, int j);
    }
}

  而後再在 AdvertisementServices 中去實現該接口

 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;

 

4、建立 Controller 接口調用

 

 

   將系統默認的ValueController刪除,手動添加一個BlogController控制器,能夠選擇一個空的,也能夠選擇一個帶有默認讀寫實例的。以下:

  

  [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)
        {
        }
    }

  接下來,在應用層添加服務層的引用

using Blog.Core.IServices;
using Blog.Core.Services;

   而後,改寫Get方法

 ·······// GET: api/Blog
        /// <summary>
        /// Sum接口
        /// </summary>
        /// <param name="i">參數i</param>
        /// <param name="j">參數j</param>
        /// <returns></returns>
        [HttpGet]
        public int Get(int i,int j)
        {
            IAdvertisementServices advertisementServices = new AdvertisementServices();
            return advertisementServices.Sum(i,j);
        }

  F5 運行項目,調試以下:

  天呀!出錯辣!別慌,還記得昨天我們加的權限麼,嗯!就是那裏,手動模擬登錄,獲取Token,注入,不會的能夠看上一篇,而後再執行,結果:

  

 

 

 

 

5、結語

  好啦,今天的工做暫時到這裏了,你能夠看到總體項目的搭建,結構,如何引用,如何測試等,固然,這裏仍是有不少小問題,好比:

  ·若是每一個倉儲都須要這麼寫,至少是四遍,會不會太麻煩;

  ·每次Controller接口調用,須要引入不少命名空間

  ·等等等等

  這些問題,下一節咱們都會帶你們一塊兒去慢慢解決!

 

6、Github && Gitee

 
https://github.com/anjoy8/Blog.Core.git

https://gitee.com/laozhangIsPhi/Blog.Core

相關文章
相關標籤/搜索