主頁 > .NET開發 > asp.net core 3.x 通用主機原理及使用

asp.net core 3.x 通用主機原理及使用

2020-09-18 17:32:25 .NET開發

一、前言

只是講asp.net core 3.x通用主機的大致原理,這些東西是通過查看原始碼以及自己根據經驗總結得來的,在文章中不會深入原始碼,因為個人覺得懂原理就曉得擴展點,后期碰到有需求的時候再仔細去研究原始碼也不遲,
閱讀前你應該先去了解下(推薦博客園老A的博客):

  • asp.net core中的依賴注入、
  • 配置,

講解的方式是:

  1. 概述
  2. 逐一介紹核心類及擴展方式
  3. 通常我們如何使用
  4. 總結

二、概述

以前的控制臺應用程式、winform程式啟動時main首先被執行,后續都是我們自己的代碼來實作框架和業務上的東東,比如我們要使用配置就ConfigurationManager.AppSettings... 若想使用依賴注入則需要引入第三方框架,比如autofact,asp.net framework時代也類似

在.net core 3.0之前的版本默認使用的是IWebHost,它內部定義了IOC容器(服務注冊體現在Startup.ConfigServices),和各種配置源的設定(體現在Program配置主機時),我們后續的Controler、View、包括業務代碼可以很容易做依賴注入和獲取配置資訊(包括運用選項模式)

有時候我們希望寫一個服務,但是這個服務并不是用來做api/web,處理http請求的,比如想做一個物聯網的后端采集服務,一直等待遠端硬體設備提交實時資料過來,后端進行處理,但是又希望使用asp.net core提供的 配置、依賴注入、日志 和其它功能,后來微軟就將asp.net core中的這套東西抽離出來了,叫做通用主機,用來承載任何服務,這些自定義服務中就可以很方便地使用配置、依賴注入、日志、和其它功能,現在asp.net core只是由通用主機承載的其中一種服務,

2.1、默認情況下主要的實作思路是:

2.1.1、定義(微軟定義好的):

  • 定義HOST,它包含IOC根容器、主機和應用程式的生命周期事件定定義、IHostedService集合(一個實體就是一個服務或者叫應用,asp.net core就是一個這樣的實體)
  • 允許呼叫方提供一堆委托來向IOC中注冊服務、和設定主機和應用的“配置源”
  • 提供向主機添加IHostedService的實作物件的方法
  • 允許呼叫方注冊主機和應用在啟動和停止階段觸發的相應事件

2.1.2、配置(我們的代碼,微軟定義很多輔助方法):

  • 創建IHost實體
  • 向Host的IOC容器中注冊各種服務
  • 配置主機和應用程式的“配置源
  • 向主機內部添加IHostedService實體(也就是我們最終的服務)
  • 主機和應用的生命周期事件,來實作一些特殊任務

2.1.3、啟動階段(微軟定義好的)

  • 上面所謂的配置基本都是通過委托實作的(通常微軟提供的各種擴展方法最終也是執行委托),回呼這些委托以設定“配置源”和注冊服務
  • 最后遍歷啟動HostedService
  • 在啟動程序中還會回呼相應的生命周期事件

2.2、啥是應用?

上面提了幾次“應用”,現在對于主機來說asp.net core框架就是一個應用、我們上面舉例說的"物聯網后端服務"是另一個應用,從代碼上來說就是一個IHostedService的實作,
主機和應用是一對多的關系,多個應用可以共享主機的資訊,如:主機的IOC容器、主機的配置,應用配置,應用當然也可以自己去創建自己的IOC根容器和配置物件

主機配置和應用配置有關系?這兩個配置物件都存在于Host中,主機配置是只跟主機相關的配置,應用配置是主機中多個應用共享的配置,如果主機中只有一個應用,那么完全可以拿它做最終的應用配置,另外應用配置包含主機配置

注意:在理解時要記住我們現在的目的是講解通用主機,意思是可以承載你自己定義的服務的主機,別去想什么mvc controller action 路由之類的

三、核心類

下面分別介紹下主機中的幾個核心默認實作類,幾乎每個類都有對應的介面,為了縮短篇幅、便于理解就不講介面了,

3.1、Host

它代表主機,用來宿主(承載)我們應用(一個IHostedService的實作),
主要包含:日志、主機和應用的生命周期事件、IOC根容器、主機的選項物件、啟動停止/停止方法,
介面中只定義了:IOC根容器 + Start + Stop方法
它在Program.Main中被創建、配置和啟動

默認實作Microsoft.Extensions.Hosting.Internal.Host,它是一個internal的類,這個主機將來被啟動時:

  • 觸發主機的WaitForStartAsync事件
  • 逐一啟動主機內部的hostedService
  • 觸發_applicationLifetime?.NotifyStarted();事件
  • 停止時就反過來,先逐一停止hostedService,觸發回應事件、最后停止主機

擴展:

因為默認Host是internal修飾的,所以無法繼承

  • 自定義實作IHost;(這不說了,你可以隨心所欲)
  • 訂閱主機和應用的生命周期事件(實作IHostLifetime、IHostApplicationLifetime并添加到IOC容器)

大部分情況下方式2實作起來更容易也更常見

提一嘴,asp.net core 3.x現在也是使用的這個默認主機,只是在上面做了根web相關的配置,將在下一篇講解

3.2、HostBuilder

Host的職責只是完成主機該有的功能,那么它的創建及配置最好另外定義一個類HostBuilder,它是Host的創建器(工廠),我們通常

  • 在系統啟動時(Program.Man)先創建HostBuilder,
  • 然后進行配置(向IOC容器注冊服務,設定主機和應用的"配置源"),
  • 最后呼叫Build方法生成我們最終的Host

通過介面IHostBuilder原始碼可以初略看出它(通過委托的方式)提供以下功能

  • 設定主機和應用的“配置源”
  • 配置IOC容器本身
  • 想IOC容器添加服務
  • 創建Host
  • 有個Properties屬性,是個字典型別,可以在構建Host的多個步驟中傳遞資料

擴展:

對于我們使用者來說主要是通過它的方法向內部塞入各種委托,以達到向IOC容器注冊服務和設定主機和應用的“配置源”
也可以但估計很少去實作主機的IHostBuilder;繼承HostBuilder意義也不大,因為它沒有提供抽象和虛方法

默認Build流程
初始化主機配置物件IConfiguration,主要是回呼,主機沒有做其它的
初始化主機環境物件_hostingEnvironment

  • 應用程式名字從上一步的主機配置里來
  • 環境名(開發?除錯?)從配置里來,若沒有則默認是生產模式"Production"
  • 內容根也從配置里來,若沒有則是當前程式路徑
  • 根據內容跟創建一個ContentRootFileProvider 實作類是PhysicalFileProvider

初始化HostBuilderContext,根據上面的配置和環境創建這個背景關系(這里只是暫時用的主機配置,下面會被替換成應用的配置)
初始化應用配置

  • 以上面的內容根作為配置查找的根(若將來提供物理檔案作為配置源時需要此屬性)
  • 將主機配置塞入這個應用配置,所以應用配置=主機配置+回呼后的配置
  • 最后將HostBuilderContext的Configuration替換為此配置物件

創建IOC容器

  • 創建ServiceCollection,并將上面的幾個物件以單利模式放入進去
  • 還要放入IHostApplicationLifetime和IHostLifetime和Host
  • 開啟選項模式,注冊日志
  • 回呼configureServicesAction
  • 呼叫工廠_serviceProviderFactory創建ServiceProvider
  • 回呼_configureContainerActions
  • 最后回傳容器

呼叫容器決議并回傳Host

3.3、HostBuilder的工廠方法Host.CreateDefaultBuilder

上面有了Host,也有了對應的創建器HostBuilder,為啥還要再提供一個工廠方法呢?
因為職責分離原則,Host只負責承載應用并提供容器和設定配置源;HostBuilder只是負責配置并創建Host,盡可能提供一些默認值(前提時將來呼叫方未提供那些引數),此時我們可以直接用HostBuilder來創建Host并啟動它,但別忘了.net core是一個通用框架,它應提供一個更簡潔的方式來創建最終的Host,因此它提供了靜態方法Host.CreateDefaultBuilder,它盡可能提供更多的默認值,核心任務如下:

  • new HostBuilder
  • 設定程式的當前目錄為內容根
  • 為主機配置 設定 環境變數作為配置源(只關注前綴DOTNET_的環境變數)
  • 為應用配置設定 以“appsettings.json”和“appsettings.{env.EnvironmentName}.json”作為配置源;同時也將環境變數加入到應用的配置源;最后將命令列引數加入到配置源
  • 配置日志
  • 若是開發模式,還會配置依賴注入的范圍驗證

四、從使用者的角度來說

通過自定義實作IHostedService的類來實作我們的服務,我們的服務中的類可以

  • 直接使用依賴注入,
  • 也可以通過依賴注入獲取主機配置和全域應用配置物件,或者更方便的是進一步使用選項模式
  • 我們也可以注入日志記錄器
  • 由于主機創建程序的相關資料幾乎都放進了IOC容器中,因此我們也可以通過依賴注入拿到
  • 其它...

在Program.man呼叫Host.CreateDefaultBuilder,如果需要,提供相應的委托來注冊服務和設定主機和應用的“配置源”,最好是通過相關擴展方法和自定義擴展方法,重點是記得注入我們自己的服務實作類

五、總結

.net core為我們提供了新的承載應用(包括但不僅限于asp.net core)的方式-->通用主機,通過它我們可以很容易的在自己的應用中使用依賴注入、配置、日志等,你可以發揮想象實作很多牛B的框架,
asp.net core 3.x開始默認也是使用它來承載的
核心的Host、HostBuilder、Host.CreateDefaultBuilder實作了通用主機,并提供了擴展點

最后我想說如果在.net core上提供一個默認的aop方案就更完美了,
下一篇試試說下asp.net core是如何承載到通用主機上的

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/75384.html

標籤:.NET Core

上一篇:使用ASP.NET Core 3.x 構建 RESTful API - 4.2 過濾和搜索

下一篇:Wireshark抓包,帶你快速入門

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more