一張圖理清ASP.NET Core啟動流程

来源:http://www.cnblogs.com/sheng-jie/archive/2017/10/09/7640163.html
-Advertisement-
Play Games

1. 引言 對於ASP.NET Core應用程式來說,我們要記住非常重要的一點是:其本質上是一個獨立的控制台應用,它並不是必需在IIS內部托管且並不需要IIS來啟動運行(而這正是ASP.NET Core跨平臺的基石)。ASP.NET Core應用程式擁有一個內置的 Self Hosted(自托管) ...


ASP.NET Core知多少系列:總體介紹及目錄

1. 引言

對於ASP.NET Core應用程式來說,我們要記住非常重要的一點是:其本質上是一個獨立的控制台應用,它並不是必需在IIS內部托管且並不需要IIS來啟動運行(而這正是ASP.NET Core跨平臺的基石)。ASP.NET Core應用程式擁有一個內置的Self-Hosted(自托管)Web Server(Web伺服器),用來處理外部請求。

不管是托管還是自托管,都離不開Host(宿主)。在ASP.NET Core應用中通過配置並啟動一個Host來完成應用程式的啟動和其生命周期的管理(如下圖所示)。而Host的主要的職責就是Web Server的配置和Pilpeline(請求處理管道)的構建。
ASP.NET Core總體啟動流程

這張圖描述了一個總體的啟動流程,從上圖中我們知道ASP.NET Core應用程式的啟動主要包含三個步驟:

  1. CreateDefaultBuilder():創建IWebHostBuilder
  2. Build():IWebHostBuilder負責創建IWebHost
  3. Run():啟動IWebHost

所以,ASP.NET Core應用的啟動本質上是啟動作為宿主的WebHost對象。
其主要涉及到兩個關鍵對象IWebHostBuilderIWebHost,它們的內部實現是ASP.NET Core應用的核心所在。下麵我們就結合源碼並梳理調用堆棧來一探究竟!

2. 宿主構造器:IWebHostBuilder

在啟動IWebHost宿主之前,我們需要完成對IWebHost的創建和配置。而這一項工作需要藉助IWebHostBuilder對象來完成的,ASP.NET Core中提供了預設實現WebHostBuilder。而WebHostBuilder是由WebHost的同名工具類(Microsoft.AspNetCore命名空間下)中的CreateDefaultBuilder方法創建的。

CreateDefaultBuilder()調用堆棧

從上圖中我們可以看出CreateDefaultBuilder()方法主要幹了六件大事:

  1. UseKestrel:使用Kestrel作為Web server。
  2. UseContentRoot:指定Web host使用的content root(內容根目錄),比如Views。預設為當前應用程式根目錄。
  3. ConfigureAppConfiguration:設置當前應用程式配置。主要是讀取 appsettinggs.json 配置文件、開發環境中配置的UserSecrets、添加環境變數和命令行參數 。
  4. ConfigureLogging:讀取配置文件中的Logging節點,配置日誌系統。
  5. UseIISIntegration:使用IISIntegration 中間件。
  6. UseDefaultServiceProvider:設置預設的依賴註入容器。

創建完畢WebHostBuilder後,通過調用UseStartup()來指定啟動類,來為後續服務的註冊及中間件的註冊提供入口。

3. 宿主:IWebHost

在ASP.Net Core中定義了IWebHost用來表示Web應用的宿主,並提供了一個預設實現WebHost。宿主的創建是通過調用IWebHostBuilderBuild()方法來完成的。那該方法主要做了哪些事情呢,我們來看下麵這張【ASP.NET Core啟動流程調用堆棧】中的黃色邊框部分:

ASP.NET Core啟動流程調用堆棧

其核心主要在於WebHost的創建,又可以劃分為三個部分:

  1. 構建依賴註入容器,初始通用服務的註冊:BuildCommonService();
  2. 實例化WebHost:var host = new WebHost(...);
  3. 初始化WebHost,也就是構建由中間件組成的請求處理管道:host.Initialize();

3.1. 註冊初始通用服務

BuildBuildCommonService方法主要做了兩件事:

  1. 查找HostingStartupAttribute特性以應用其他程式集中的啟動配置
  2. 註冊通用服務
  3. 若配置了啟動程式集,則發現並以IStartup類型註入到IOC容器中

3.2. 創建IWebHost

public IWebHost Build()
{
    //省略部分代碼

    var host = new WebHost(
        applicationServices,
        hostingServiceProvider,
        _options,
        _config,
        hostingStartupErrors);
    }
    
    host.Initialize();

    return host;
}

3.3. 構建請求處理管道

請求管道的構建,主要是中間件之間的銜接處理。

而請求處理管道的構建,又包含三個主要部分:

  1. 註冊Startup中綁定的服務;
  2. 配置IServer;
  3. 構建管道

請求管道的構建主要是藉助於IApplicationBuilder,相關類圖如下:
請求管道的構建

4. 啟動WebHost

WebHost的啟動主要分為兩步:

  1. 再次確認請求管道正確創建
  2. 啟動Server以監聽請求
  3. 啟動 HostedService

啟動WebHost調用堆棧

4.1. 確認請求管道的創建

從圖中可以看出,第一步調用Initialize()方法主要是取保請求管道的正確創建。其內部主要是對BuildApplication()方法的調用,與我們上面所講WebHost的構建環節具有相同的調用堆棧。而最終返回的正是由中間件銜接而成的RequestDelegate類型代表的請求管道。

4.2. 啟動Server

我們先來看下類圖:

IServer類圖

從類圖中我們可以看出IServer介面主要定義了一個只讀的特性集合屬性、一個啟動和停止的方法聲明。在創建宿主構造器IWebHostBuilder時我們通過調用UseKestrel()方法指定了使用KestrelServer作為預設的IServer實現。其方法申明中接收了一個IHttpApplication<TContext> application的參數,從命名來看,它代表一個Http應用程式,我們來看下具體的介面定義:

IHttpApplication類圖

其主要定義了三個方法,第一個方法用來創建請求上下文;第二個方法用來處理請求;第三個方法用來釋放上下文。而至於請求上下文,是用來攜帶請求和返迴響應的核心參數,其貫穿與整個請求處理管道之中。ASP.NET Core中提供了預設的實現HostingApplication,其構造函數接收一個RequestDelegate _application(也就是鏈接中間件形成的處理管道)用來處理請求。

var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
var hostingApp = new HostingApplication(_application, _logger, diagnosticSource, httpContextFactory);

4.3. 啟動IHostedService

IHostedService介面用來定義後臺任務,通過實現該介面並註冊到Ioc容器中,它會隨著ASP.NET Core 程式啟動而啟動,終止而終止。

5. 總結

結合源碼,通過對ASP.NET Core運行調用堆棧的梳理,其啟動流程的總體脈絡一目瞭然,並且瞭解到主要的幾個關鍵對象:

  1. 負責創建IWebHost的宿主構造器IWebHostBuilder
  2. 代表宿主的IWebHost介面
  3. 用於構建請求管道的IApplicationBuilder
  4. 中間件銜接而成的RequestDelegate
  5. 代表Web Server的IServer介面
  6. 貫穿請求處理管道的請求上下文HttpContext
  7. 可以用來註冊後臺服務的IHostedService介面

這一節就先從總體上對ASP.NET Core的運行原理有個基本的認識,後續我們再一一講解這幾個核心對象來加深理解。


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

-Advertisement-
Play Games
更多相關文章
  • 首先解釋下:本文只是對Asp.net MVC4高級編程這本書學習記錄的學習筆記,書本內容感覺挺簡單的,但學習容易忘記,因此在邊看的同時邊作下了筆記,可能其它朋友看的話沒有情境和邏輯順序還請諒解! 一、MVC控制器渲染視圖的三種方式。 如下以HomeController控制器中的代碼為例: 1、預設方 ...
  • 局部函數是C 7中的一個新功能,允許在一個函數中定義另一個函數。 何時使用局部函數? 局部函數的主要功能與匿名方法非常相似:在某些情況下,創建一個命名函數在讀者的認知負擔方面代價太大。有時,函數本身就是另一個函數的部分邏輯,因此用一個單獨的命名實體來污染“外部”範圍是毫無意義的。 您可能認為此功能是 ...
  • 在數值字元串的格式化中有很多格式化的格式,比如:用"C"表示貨幣格式,用"P"表示百分比格式,FCL中支持多種格式化字元串的方式。有時候我們會把一個數值轉換成string類型,然後再從string類型轉換成數值類型,這時候就要考慮轉換回來後的數值會不會和原來的相等呢? 首先的一種情況: 使用G常規格 ...
  • 基於ffmpeg和虹軟人臉識別庫的C#開源實現,對虹軟人臉識別庫進行了包裝,便於在C#中快速、安全的調用識別函數。同時,開源代碼中,包含完整的實現示例。 ...
  • 本篇作為技術分享系列的第四篇,詳細講一下手繪視頻中 Surface Pen 和 Surface Dial 的使用場景。 先放一張微軟官方商城的圖,Surface 的使用中結合了 Surface Pen 和 Surface Dial。 Surface Pen 的使用場景不難想象,就像 iPad 和 A ...
  • DataRead 和DataSet區別 dataset表示一個數據集,是數據在記憶體中的緩存。 可以包括多個表DatSet 連接資料庫時是非面向連接的。把表全部讀到Sql中的緩衝池,並斷開於資料庫的連接 datareader 連接資料庫時是面向連接的。讀表時,只能向前讀取,讀完數據後有用戶決定是否斷開 ...
  • C# 的集合類型中, 都有Synchronized靜態方法, 和SyncRoot實例方法 對於ArrayList以及Hashtable 集合類來講,當需要做到線程安全的時候,最好利用其自帶的屬性SyncRoot 來做到,儘管也可以使用其Synchronized()方法來實現,但是使用屬性會更好。 線 ...
  • XAML代碼: <local:WorkSpaceContent x:Class="SunCreate.CombatPlatform.Client.NoticeMarquee" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentati ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...