asp.net core系列 71 Web架構分層指南

来源:https://www.cnblogs.com/MrHSR/archive/2019/08/23/11272400.html
-Advertisement-
Play Games

一.概述 本章Web架構分層指南,參考了“Microsoft應用程式體繫結構指南”(該書是在2009年出版的,當時出版是為了幫助開發人員和架構師更快速,更低風險地使用Microsoft平臺和.NET Framework設計和構建有效,高質量的應用程式)。雖然已過去十年了,技術架構已更新(如流行的DD ...


一.概述

  本章Web架構分層指南,參考了“Microsoft應用程式體繫結構指南”(該書是在2009年出版的,當時出版是為了幫助開發人員和架構師更快速,更低風險地使用Microsoft平臺和.NET Framework設計和構建有效,高質量的應用程式)。雖然已過去十年了,技術架構已更新(如流行的DDD/CQRS模式,微服務,容器),但web分層思想還是一樣可取,下麵是一個“傳統N分層設計”架構圖,該架構在2010年左右是最流行的,包括了表現層presentation,服務層services,業務層business,數據訪問層data,橫切關註點cross,如下所示:

  

  對比傳統多層或三層.net web架構,下圖是當前流行的.net web微服務架構,在web程式分層之上還包含了容器,web api網關,各服務對應的數據存儲(sqlserver,redis,mongoDB),web程式有web api並結合應用了DDD\CQRS分層模式,以及系統各種中間件。

  

  下圖是一個訂單微服務站點,包含了簡化的cqrs分層,藍色長方格是表示cqrs分層的職責,包括了查詢 Queries viewModels和命令Command Domain-Model以及上層的應用服務層Application,如下所示

 

  1.1 邏輯分層設計架構類型

    (1) 最傳統的分層是經典三層設計,包括表現層,業務層,數據層.

    (2) 基於服務的解決方案SOA,公開應用程式業務功能的服務層,服務層在業務層之上。

    (3) 基於領域驅動設計的DDD\CQRS分層模式

    (4) 微服務架構

     這4種web分層架構是不斷的演化改變 ,每一種分層架構並不是獨立的思想,它包含了演化之前的架構分層思想。從以前三層架構到現在的微服務架構,是適應每個時代互聯網業務實現的需求。

功能

SOA

微服務

組件大小

大塊業務邏輯

單獨任務或小塊業務邏輯

耦合

通常松耦合

總是松耦合

公司架構

任何類型

小型、專註於功能交叉團隊

管理

著重中央管理

著重分散管理

目標

確保應用能夠交互操作

執行新功能、快速拓展開發團隊

 

.Web分層設計步驟

  1.分層策略
    (1)分層粒度是確定分層策略的關鍵第一步.
    (2)在邏輯分層中, 多層是在同一進程中運行,這可以利用更高性能的通信機制。例如通過組件介面直接調用。必須小心保持層之間的封裝和鬆散耦合。
    (3)在物理分層中,確定合適的通信機制,該機制考慮到通信延遲並保持之間的鬆散耦合。
    (4)多層中,考慮它們之間如何相互影響,將確保性能和靈活性之間的良好平衡。

 

  2.確定需要層
    最常用的方法是將表現層,服務層,業務層和數據訪問層功能分離到單獨的層中。某些應用程式還引入了各種組件像緩存、日誌、消息隊列等。

 

  3.決定如何分發各層和組件
    對於web體系架構,一般都是在一個物理層,只有在必要時,才應在不同的物理層上分佈層和組件。這是實現分散式部署的常見原因包括安全策略,物理約束,共用業務邏輯和可伸縮性。

 

  4.確定是否需要摺疊層
    一般規則是您應始終將功能分組到層中。在某些情況下,一個層可以充當代理或傳遞層,提供封裝和鬆散耦合,而不提供大量功能。但是,通過分離該功能,您可以稍後對其進行擴展,而對設計中的其他層幾乎沒有影響,如:應用服務層。

 

  5.確定層之間引用的規則
    在分層策略時,您必須定義層如何相互交互的規則(交互是指:各層引用的關係)。指定交互規則的主要原因是最小化依賴性並消除迴圈引用。因此應該遵循以下方法之一:
    (1)自上而下的交互
      較高級別的層可以與下麵的層交互,但是較低級別的層不應該與上面的層交互。此規則將幫助您避免層之間的迴圈依賴關係,以及要降低層之間的依賴性。
    (2)嚴格的互動
      每個層必須僅與下麵的層進行交互。此規則將強制嚴格分離關註點,其中每個層僅知道下麵的層。此規則的好處是對層界面的修改只會影響上面的層。如果您正在設計一個將隨著時間的推移進行修改以引入新功能並且您希望最大限度地減少這些更改的影響的應用程式,或者您正在設計可能分佈在不同物理層上的應用程式,請考慮使用此方法。
    (3)鬆散的互動
      較高級別的層可以繞過層直接與較低級別的層交互。這可以提高性能,但也會增加依賴性換句話說,對較低級別層的修改可以影響上面的多個層

    下圖是一個示例:該web架構示例是使用了 cqrs 模式,涉及到了事件源es, 事件源實現本因該分離到命令域和查詢域, 而項目中應用服務層直接引用了底層數據訪問層Dapper(繞過了領域層),  這樣底層Dapper介面方法的修改或換成EF將影響頂層應用服務層,這屬於第三種"鬆散的互動"。 應該推薦使用第一種自上而下的交互。

 

  6.確定跨領域問題
    定義層後,必須標識跨越層的功能。此功能通常被描述為橫切關註點,包括日誌記錄,緩存,驗證,身份驗證和異常管理。確定應用程式中的每個橫切關註點非常重要,並設計單獨的組件以儘可能地管理這些問題。此方法可幫助您實現更好的可重用性和可維護性。
    如下圖所示:NLog與Redis是具體實現組件,實現了Common層中的日誌和緩存介面,Common層就是橫切組件,是跨層可重用的。像Ioc也是橫切組件。 下圖層的名稱沒有標識跨越層的功能,如果是GFNetCore.Infra.CrossCutting.IoC 這樣命名會更好。

 

  7.定義層之間的介面
    為層定義介面時,主要目標是強制層之間的鬆散耦合。這意味著層不應暴露另一層可能依賴的內部細節。相反,層的介面應設計為通過提供隱藏層內組件細節的公共介面來最小化依賴性。這種隱藏稱為抽象,有許多不同的方法來實現它。以下設計方法可用於定義層的介面:

    (1)抽象介面
      通過定義抽象基類或介面類來實現,該類充當具體類的類型定義。該類型定義了一個公共介面,該層的所有使用者都使用該介面與該層進行交互。這是一種面向介面編程,例如:表現層調用應用服務層的介面。表現層在CustomerController控制器中如下所示(通過依賴註入後,構造方法來實例):

     //表現層調用應用服務層ApplicationService
        private readonly ICustomerAppService _customerAppService;

        public CustomerController(ICustomerAppService customerAppService, 
                                  INotificationHandler<DomainNotification> notifications) : base(notifications)
        {
            _customerAppService = customerAppService;
        }

      但在項目中,為了簡化開發量,表現層調用應用服務層的實現類(違反了面向介面編程)。表現層在CustomerController控制器中如下所示:

        //調用應用服務層ApplicationService
        private readonly CustomerAppService _customerAppService = null;

        //日誌對象
        public readonly ILoggerEX _logger;

        public CustomerController(INotificationHandler<DomainNotification> notifications,
                                  ILoggerEX logger,
                                  CustomerAppService customerAppService)
            : base(notifications)
        {
            _customerAppService = customerAppService;
            _logger = logger;
        }

    (2)依賴倒置

      這是一種編程風格,是面向介面編程的實現,依賴倒置的應用如:DDD\CQRS, 層依賴於層介面,而不是層依賴於另一個層的實現。依賴註入模式是依賴性反轉的常見實現。依賴性反轉方法提供了靈活性,可以幫助實現可插入設計,因為依賴性是通過配置而不是代碼組成的。它還可以最大化可測試性,因為您可以輕鬆地將具體測試類註入到設計的不同層中。

      依賴性是通過配置的,如下代碼所示,由CommandRepository類來實現ICommandRepository介面:

        services.AddScoped<ICommandRepository<CommandModels.Customer>, CommandRepository<CommandModels.Customer>>();
        services.AddScoped<IQueryRepository<QueryModels.Customer>, QueryRepository<QueryModels.Customer>>();

 

    (3) 基於消息

      可以使用基於消息的通信來實現介面並提供層之間的交互,.net技術如:wcf, web services, msmq它們支持跨物理和進程邊界的交互(以xml的soap格式傳輸),但這是對於09年流行的web架構。現在基於消息多數用web api技術,是面向微服務開發(以json的rest api)。

 

 

 參考資料

   分層應用程式指南 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。原文出處:https://www.infoq.cn/article/xPTBAR9-oJcVtUjTQ0tK 我一直回想我的第一篇博文,那是關於多個服務的伺服器平臺的詳細教程,它使用 GitLab CI 在 A ...
  • 測試代碼: private void TestDistinct() { Task.Run(() => { //生成測試數據 DateTime dt = DateTime.Now; Random rnd = new Random(); List<MyData> list = new List<MyDa ...
  • 公司的項目架構演進,我們也趁機嘗試遷移到netcore,系列隨筆講記錄我們的踩坑和填坑記錄。 HttpClient不行? 這是我們第一次嘗試netcore 簡要介紹環境 netcore2.2+aspnetcore2.2+windows 2008R2+SqlServer2008R2 問題場景 支付寶支 ...
  • 文章起源來自一篇博客: "使用 .NET CORE 創建 項目模板,模板項目,Template DeepThought 博客園" 之前使用Abp的時候就很認同Abp創建模板項目的方式。想不到.Net Core出了更贊的方式創建模板。之前寫過一個系列文章,有不少對Abp框架的改動(見文章: "基於.N ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
  • .NET Core 中三種模式依賴註入的生命周期簡要說明 ...
  • 電子發票是電商時代的產物,PDF發票是最常見的電子發票之一。在這篇文章中,我將給大家分享一個免費的動態生成PDF電子發票的C#方案,併在文章末尾附上Java解決方案。 典型的發票包含客戶和供應商的名稱和地址、發票編號、購買物品的描述、付款金額等信息。為了動態地生成發票,我使用MS Word創建了一個 ...
  • 在開發個人博客的時候,用到了騰訊移動分析(MTA),相比其他數據統計平臺來說我喜歡她的簡潔高效,易上手,同時文檔也比較全面,提供了數據介面供用戶調用。 在看了MTA演示 "Demo" 和 "官方文檔" 後,我就決定使用 .NET Core將其HTML5統計API進行封裝,以供博客直接調用,省去各種鑒 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...