日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET Core技术研究-主机

發(fā)布時間:2023/12/4 asp.net 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core技术研究-主机 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前一段時間,和大家分享了?ASP.NET Core技術(shù)研究-探秘Host主機啟動過程

但是沒有深入說明主機的設(shè)計。今天整理了一下主機的一些知識,結(jié)合先前的博文,完整地介紹一下.NET Core的主機的設(shè)計和構(gòu)建啟動過程。

一、什么是主機

? 主機是一個封裝了應(yīng)用資源的對象,即:主機封裝了一堆應(yīng)用資源,封裝了哪些應(yīng)用資源呢?

  • 依賴注入框架 DI?

  • Logging日志

  • Configuration 配置

  • 托管服務(wù):IHostedService服務(wù)接口的實現(xiàn)

二、Web主機和通用主機

? ? 先說Web主機:即ASP.NET Core Web主機,概括的講就是托管Web程序的Host。在低于 3.0 的 ASP.NET Core 版本中,Web 主機用于 HTTP 工作負載

? ? 我們新建一個ASP.NET Core2.2的Web應(yīng)用程序,在Program類的Main函數(shù)中我們可以看到整個WebHost的構(gòu)造、啟動過程:

? ??

? ??

? ?.NET Core提供Web主機的同時,還提供了一個通用主機的概念。

? ?通用主機Host和Web主機提供了類似的架構(gòu)和功能,包含依賴注入框架DI、日志、配置、各類應(yīng)用(托管服務(wù))。通用主機的出現(xiàn),給了我們更多開發(fā)的選擇,比如說后臺處理任務(wù)場景。

? ?在.NET Core3.1版本后,微軟不再建議將 Web 主機用于 Web 應(yīng)用,直接使用Host通用主機來替換WebHost,

? ?一句話:通用主機可以托管任何類型的應(yīng)用,包括 Web 應(yīng)用。通用主機將替換 Web 主機。為了向下兼容,WebHost依然可以使用。

? ??我們新建一個ASP.NET Core3.1的Web應(yīng)用程序,在Program類的Main函數(shù)中我們可以看到整個WebHost的構(gòu)造、啟動過程:

? ??

? ?接下來,我們將以ASP.NET Core 3.1這個版本,介紹一下主機的構(gòu)建過程和啟動過程

三、主機是如何構(gòu)建的

? ?從上述代碼可以看到,Main函數(shù)中首先調(diào)用CreateHostBuilder方法,返回一個IHostBuilder。然后調(diào)用IHostBuilder.Build()方法完成

? 1. 通過Host.CreateDefaultBuilder(args): 構(gòu)造IHostBuilder的默認實現(xiàn)HostBuilder

???在CreateHostBuilder方法內(nèi)部,首先調(diào)用了Host.CreateDefaultBuilder構(gòu)造了一個HostBuilder,這個我們先看下源碼,看看到底Host類內(nèi)部做了什么操作:

public static IHostBuilder CreateDefaultBuilder(string[] args){var builder = new HostBuilder();builder.UseContentRoot(Directory.GetCurrentDirectory());builder.ConfigureHostConfiguration(config =>{config.AddEnvironmentVariables(prefix: "DOTNET_");if (args != null){config.AddCommandLine(args);}});builder.ConfigureAppConfiguration((hostingContext, config) =>{var env = hostingContext.HostingEnvironment;config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName)){var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));if (appAssembly != null){config.AddUserSecrets(appAssembly, optional: true);}}config.AddEnvironmentVariables();if (args != null){config.AddCommandLine(args);}}).ConfigureLogging((hostingContext, logging) =>{var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);// IMPORTANT: This needs to be added *before* configuration is loaded, this lets// the defaults be overridden by the configuration.if (isWindows){// Default the EventLogLoggerProvider to warning or abovelogging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);}logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));logging.AddConsole();logging.AddDebug();logging.AddEventSourceLogger();if (isWindows){// Add the EventLogLoggerProvider on windows machineslogging.AddEventLog();}}).UseDefaultServiceProvider((context, options) =>{var isDevelopment = context.HostingEnvironment.IsDevelopment();options.ValidateScopes = isDevelopment;options.ValidateOnBuild = isDevelopment;});return builder;}

  

從上述.NET Core源代碼中,可以看到CreateDefaultBuilder內(nèi)部構(gòu)造了一個HostBuilder,同時設(shè)置了:

  • 將內(nèi)容根目錄(contentRootPath)設(shè)置為由 GetCurrentDirectory 返回的路徑。

  • 通過以下源加載主機配置

    • 環(huán)境變量(DOTNET_前綴)配置

    • 命令行參數(shù)配置

  • ? ? ?通過以下對象加載應(yīng)用配置

    • appsettings.json?

    • appsettings.{Environment}.json

    • 密鑰管理器 當(dāng)應(yīng)用在 Development 環(huán)境中運行時

    • 環(huán)境變量

    • 命令行參數(shù)

  • ? ? ?添加日志記錄提供程序

    • 控制臺

    • 調(diào)試

    • EventSource

    • EventLog( Windows環(huán)境下)

  • 當(dāng)環(huán)境為“開發(fā)”時,啟用范圍驗證和依賴關(guān)系驗證。

? ?以上構(gòu)造完成了HostBuilder,針對ASP.NET Core應(yīng)用,代碼繼續(xù)調(diào)用了HostBuilder.ConfigureWebHostDefaults方法。

? ?2. IHostBuilder.ConfigureWebHostDefaults:通過GenericWebHostBuilder對HostBuilder增加ASP.NET Core的運行時設(shè)置

? ?構(gòu)造完成HostBuilder之后,針對ASP.NET Core應(yīng)用,繼續(xù)調(diào)用了HostBuilder.ConfigureWebHostDefaults方法。這是一個ASP.NET Core的一個擴展方法:

? ?

? ?我們繼續(xù)看ConfigureWebHostDefaults擴展方法內(nèi)部做了哪些事情:

? ?ASP.NET Core源碼連接:https://github.com/dotnet/aspnetcore/blob/master/src/DefaultBuilder/src/GenericHostBuilderExtensions.cs ?? ??

? ?

using System; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore;namespace Microsoft.Extensions.Hosting {/// <summary>/// Extension methods for configuring the IWebHostBuilder./// </summary>public static class GenericHostBuilderExtensions{/// <summary>/// Initializes a new instance of the <see cref="IWebHostBuilder"/> class with pre-configured defaults./// </summary>/// <remarks>/// The following defaults are applied to the <see cref="IWebHostBuilder"/>:/// use Kestrel as the web server and configure it using the application's configuration providers,/// adds the HostFiltering middleware,/// adds the ForwardedHeaders middleware if ASPNETCORE_FORWARDEDHEADERS_ENABLED=true,/// and enable IIS integration./// </remarks>/// <param name="builder">The <see cref="IHostBuilder" /> instance to configure</param>/// <param name="configure">The configure callback</param>/// <returns>The <see cref="IHostBuilder"/> for chaining.</returns>public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Action<IWebHostBuilder> configure){return builder.ConfigureWebHost(webHostBuilder =>{WebHost.ConfigureWebDefaults(webHostBuilder);configure(webHostBuilder);});}} }

  首先,通過類GenericHostWebHostBuilderExtensions,對IHostBuilder擴展一個方法:ConfigureWebHost:builder.ConfigureWebHost

? ? ?在這個擴展方法中實現(xiàn)了對IWebHostBuilder的依賴注入:即將GenericWebHostBuilder實例傳入方法ConfigureWebHostDefaults內(nèi)部

? ? ?代碼連接:https://github.com/dotnet/aspnetcore/blob/release/3.1/src/Hosting/Hosting/src/GenericHostWebHostBuilderExtensions.cs ???

using System; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection;namespace Microsoft.Extensions.Hosting {public static class GenericHostWebHostBuilderExtensions{public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action<IWebHostBuilder> configure){var webhostBuilder = new GenericWebHostBuilder(builder);configure(webhostBuilder);builder.ConfigureServices((context, services) => services.AddHostedService<GenericWebHostService>());return builder;}} }

通過GenericWebHostBuilder的構(gòu)造函數(shù)GenericWebHostBuilder(buillder),將已有的HostBuilder增加了ASP.NET Core運行時設(shè)置。

? ?可以參考ASP.NET Core源代碼:https://github.com/dotnet/aspnetcore/blob/release/3.1/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs

? ?先看到這,讓我們回到ConfigureWebHostDefaults:

? ?將上面兩段代碼合并一下進行理解:ConfigureWebHostDefaults做了兩件事情:

? ?①.?擴展IHostBuilder增加ConfigureWebHost,引入IWebHostBuilder的實現(xiàn)GenericWebHostBuilder,將已有的HostBuilder增加ASP.NET Core運行時的設(shè)置。

? ?②??ConfigureWebHost代碼中的configure(webhostBuilder):對注入的IWebHostBuilder,調(diào)用 WebHost.ConfigureWebDefaults(webHostBuilder),啟用各類設(shè)置,如下代碼解讀:?

??

internal static void ConfigureWebDefaults(IWebHostBuilder builder){builder.ConfigureAppConfiguration((ctx, cb) =>{if (ctx.HostingEnvironment.IsDevelopment()){StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment, ctx.Configuration);}});builder.UseKestrel((builderContext, options) =>{options.Configure(builderContext.Configuration.GetSection("Kestrel"));}).ConfigureServices((hostingContext, services) =>{// Fallbackservices.PostConfigure<HostFilteringOptions>(options =>{if (options.AllowedHosts == null || options.AllowedHosts.Count == 0){// "AllowedHosts": "localhost;127.0.0.1;[::1]"var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);// Fall back to "*" to disable.options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });}});// Change notificationservices.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();if (string.Equals("true", hostingContext.Configuration["ForwardedHeaders_Enabled"], StringComparison.OrdinalIgnoreCase)){services.Configure<ForwardedHeadersOptions>(options =>{options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;// Only loopback proxies are allowed by default. Clear that restriction because forwarders are// being enabled by explicit configuration.options.KnownNetworks.Clear();options.KnownProxies.Clear();});services.AddTransient<IStartupFilter, ForwardedHeadersStartupFilter>();}services.AddRouting();}).UseIIS().UseIISIntegration();}

  其內(nèi)部實現(xiàn)了:

  • 前綴為 ASPNETCORE_ 的環(huán)境變量加載主機配置。

  • 將?Kestrel作為默認的Web服務(wù)器

  • 添加HostFiltering中間件(主機篩選中間件)

  • 如果ASPNETCORE_FORWARDEDHEADERS_ENABLED=true,添加轉(zhuǎn)接頭中間件ForwardedHeaders?

  • 啟用IIS集成

??3. 返回ConfigureWebHostDefaults代碼中的configure(webHostBuilder):執(zhí)行Program類中的webBuilder.UseStartup<Startup>();

? ?以上過程完成了IHostBuilder.ConfigureWebHostDefaults,通過GenericWebHostBuilder對HostBuilder增加ASP.NET Core的運行時設(shè)置。

? ?接下來就是主機的Build過程了:

? 4.?CreateHostBuilder(args).Build()

??CreateHostBuilder返回的IHostBuilder,我們通過代碼Debug,看一下具體的類型:Microsoft.Extensions.Hosting.HostBuilder。

??

? ?具體的Build過程是怎么樣的?先看下Build的源碼:https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/HostBuilder.cs

? ?? ?

? ? ? 主機Build的過程主要完成了:

  • BuildHostConfiguration:構(gòu)造配置系統(tǒng),初始化?IConfiguration?_hostConfiguration;

  • CreateHostingEnvironment:構(gòu)建主機HostingEnvironment環(huán)境信息,包含ApplicationName、EnvironmentName、ContentRootPath等

  • CreateHostBuilderContext:創(chuàng)建主機Build上下文HostBuilderContext,上下文中包含:HostingEnvironment和Configuration

  • BuildAppConfiguration:構(gòu)建應(yīng)用程序配置

  • CreateServiceProvider:創(chuàng)建依賴注入服務(wù)提供程序,? 即依賴注入容器

四、主機是如何啟動運行的

? ?我們先通過Debug,看一下Host的信息:Microsoft.Extensions.Hosting.Internal.Host

? ?

? ? ??這個Run方法也是一個擴展方法:HostingAbstractionsHostExtensions.Run

? ? ? ASP.NET Core源代碼鏈接:https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Abstractions/src/HostingAbstractionsHostExtensions.cs

? ? ?

? ???其實內(nèi)部轉(zhuǎn)調(diào)的還是Host.StartAsync方法,在內(nèi)部啟動了DI依賴注入容器中所有注冊的服務(wù)。

? ? ?.NET Core代碼鏈接:https://github.com/dotnet/extensions/blob/release/3.1/src/Hosting/Hosting/src/Internal/Host.cs

? ??

五、主機中注冊一個托管服務(wù)

? 以一個后臺自更新(每隔5s 檢查一次程序變更、進行輸出)場景作為Demo,我們看一下如何在主機中注冊一個托管服務(wù)。

? 自更新服務(wù)UpdateService,需要繼承接口IHostService。

??

public class UpdateService : IHostedService{Task updateTask = null;CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();public Task StartAsync(CancellationToken cancellationToken){updateTask = Task.Run(() =>{while (cancellationTokenSource.Token.IsCancellationRequested==false){<br> //Check new data...Console.WriteLine(DateTime.Now + ": Executed");Task.Delay(5000).Wait();}});return Task.CompletedTask;}public Task StopAsync(CancellationToken cancellationToken){cancellationTokenSource.Cancel();return Task.CompletedTask;}} public class UpdateService : IHostedService{Task updateTask = null;CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();public Task StartAsync(CancellationToken cancellationToken){updateTask = Task.Run(() =>{while (cancellationTokenSource.Token.IsCancellationRequested==false){<br> //Check new data...Console.WriteLine(DateTime.Now + ": Executed");Task.Delay(5000).Wait();}});return Task.CompletedTask;}public Task StopAsync(CancellationToken cancellationToken){cancellationTokenSource.Cancel();return Task.CompletedTask;}}

  同時,我們需要在ConfigureServices方法中,將UpdateService添加到IoC服務(wù)容器中

// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) {services.AddSingleton<IHostedService, UpdateService>();services.AddControllers(); }

  程序啟動后,可以看到以下輸出:

? ??

? ?以上是對.NET Core主機的概念、設(shè)計初衷、構(gòu)建過程、啟動運行過程、服務(wù)注冊的整理和分享。

往期精彩回顧



  • 【.net core】電商平臺升級之微服務(wù)架構(gòu)應(yīng)用實戰(zhàn)

  • .Net Core微服務(wù)架構(gòu)技術(shù)棧的那些事

  • Asp.Net Core 中IdentityServer4 授權(quán)中心之應(yīng)用實戰(zhàn)

  • Asp.Net Core 中IdentityServer4 授權(quán)中心之自定義授權(quán)模式

  • Asp.Net Core 中IdentityServer4 授權(quán)流程及刷新Token

  • Asp.Net Core 中IdentityServer4 實戰(zhàn)之 Claim詳解

  • Asp.Net Core 中IdentityServer4 實戰(zhàn)之角色授權(quán)詳解

  • Asp.Net Core 中間件應(yīng)用實戰(zhàn)中你不知道的那些事

  • Asp.Net Core Filter 深入淺出的那些事-AOP

  • Asp.Net Core EndPoint 終結(jié)點路由工作原理解讀

  • ASP.NET CORE 內(nèi)置的IOC解讀及使用


??給個[在看],是對我最大的支持??

總結(jié)

以上是生活随笔為你收集整理的.NET Core技术研究-主机的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。