天天看點

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

這是在Asp.Net Core 2.1加入了一種新的Host,現在2.1版本的Asp.Net Core中,有了兩種可用的Host。

Web Host –适用于托管Web程式的Host,就是我們所熟悉的在Asp.Net Core應用程式的Mai函數中用CreateWebHostBuilder建立出來的常用的WebHost。

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

Generic Host (ASP.NET Core 2.1版本才有) – 适用于托管非 Web 應用(例如,運作背景任務的應用)。 在未來的版本中,通用主機将适用于托管任何類型的應用,包括 Web 應用。 通用主機最終将取代 Web 主機,這大概也是這種類型的主機叫做通用主機的原因,在本部落格中,我們将結合源碼,讨論通用主機的工作原理。

通用主機,讓我可以用編寫Asp.Net Core的思想(例如控制反轉、依賴注入、IOC容器)來簡化控制台應用程式的建立(個人見解),主機負責程式的啟動和生存周期的管理,這對于不處理HTTP請求的應用程式非常有用(處理HTTP請求的是Web應用程式,用Web Host托管),通用主機的目标是将HTTP管道從Web Host中脫離出來,使得Asp.Net Core的那套東西也适用于其他.Net Core程式。

在開始跟随我分析通用主機之前,大家可以到Github下載下傳這個官方Demo。

https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/host/generic-host/samples/

如果覺得下載下傳一整個比較慢,可以從我的這個Github倉庫下載下傳,沒有其他多餘内容,國内Github比較慢,如果你從官方那個倉庫下載下傳可能會需要很長時間甚至失敗。

https://github.com/liuzhenyulive/Generic-Host-Demo

首先,大家打開下載下傳下來的這個官方Demo,進入Main函數。

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

可以看到,這簡直就是一個精簡版的Asp.Net Core應用程式,對這個Main函數中出現的所有方法,大家對Asp.Net Core Web應用程式比較熟悉,是以我與Asp.net core 的Webhost做了一個對比,來幫助大家找找感覺。

通用主機

Web主機

new HostBuilder()

WebHost.CreateDefaultBuilder(args)

ConfigureAppConfiguration

(用于配置Configuration)

WebHost也有這個方法,隻是大家預設可能沒有調用。

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

ConfigureServices

(用于配置Service,也就是依賴注入)

WebHost其實也有ConfigureServices方法,可以這麼調用。

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

但是我們一般很少這麼用,一般都是放在Startup的ConfigureServices方法中進行依賴注入。

ConfigureLogging

(是本應用程式所需要的配置,非必需)

WebHost還是有!

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

builder.RunConsoleAsync()

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

RunConsoleAsync中其實是對hostbuilder進行

Builder然後Run

CreateWebHostBuilder(args).Build().Run();

也就是Main函數中的Build().Run();

無無無無

Startup中的Configure()方法

Asp.net core在此方法中進行Http請求管道的配置

綜上對比,我做了如下概括!

通用主機(Generic Host)有的 Web Host都有。

Web Host的Http Pipeline即Startup.Configure() 在通用主機中沒有。

這就應證了開頭所說的:通用主機的目标是将HTTP管道從Web Host中脫離出來,使得Asp.Net Core的那套東西也适用于其他.Net Core程式。

我覺得要知道怎麼用,那麼我們就首先要知道Host的Run方法内到底是在執行什麼?

是以我們深入源碼,一路F12!

builder.RunConsoleAsync(); =>hostBuilder.UseConsoleLifetime().Build().RunAsync(cancellationToken);=> await host.StartAsync(token);

總算找到了,最關鍵的在這裡。

this._hostedServices = this.Services.GetService<IEnumerable<IHostedService>>(); foreach (IHostedService hostedService in this._hostedServices) await hostedService.StartAsync(cancellationToken).ConfigureAwait(false

知道大家都喜歡Yellow色,是以我用Yellow把最關鍵的代碼标示出來了,那麼這些代碼有什麼含義呢?

this._hostedServices = this.Services.GetService<IEnumerable<IHostedService>>();

這一行的意思是,從容器中取出所有實作了IHostedService的服務。

這就意味着,我們實作了IHostedService後,需要把該Service注冊到IOC容器中。

foreach (IHostedService hostedService in this._hostedServices)

      await hostedService.StartAsync(cancellationToken).ConfigureAwait(false);

執行每個服務的StartAsync方法。

是以,大家是不是冥冥中猜到了怎麼用的呢?

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

我總結的步驟如下:

自定義一個Service,繼承 IHostedService接口。

實作 IHostedService的StartAsync方法,把需要執行的任務放到這個方法中。

把該服務注冊到IOC容器(ServiceCollection)中。

可以看到,在StartAsync中,定義了一個定時任務,帶定時任務每五秒執行一次DoWork方法。

在DoWork方法中,日志記錄器記錄了一段内容。

因為在Main方法中,對Log進行了如下的配置。

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

是以,一旦日志記錄了内容,該内容就會在控制台中輸出。

<IHostedService, PrintTextToConsoleService>

黃色部分,把實作了IHostedService接口的PrintTextToConsoleService注冊到容器中。

Asp.net Core 2.1新功能Generic Host(通用主機),了解一下

可以看到,控制台中,每五秒就有一次内容輸出,說明DoWork方法沒五秒被執行了一次,也說明PrintTextToConsoleService的StartAsync被成功調用了。

希望本文對幫助大家了解通用主機能夠有所幫助,如果對.Net Core的源碼分析、潮流新技術感興趣

歡迎關注我

不定期推出實用幹活,謝謝!

參考文獻

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.1