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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET Core技术研究-主机

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

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

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

一、什么是主機

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

  • 依賴注入框架 DI?

  • Logging日志

  • Configuration 配置

  • 托管服務:IHostedService服務接口的實現

二、Web主機和通用主機

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

? ? 我們新建一個ASP.NET Core2.2的Web應用程序,在Program類的Main函數中我們可以看到整個WebHost的構造、啟動過程:

? ??

? ??

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

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

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

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

? ??我們新建一個ASP.NET Core3.1的Web應用程序,在Program類的Main函數中我們可以看到整個WebHost的構造、啟動過程:

? ??

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

三、主機是如何構建的

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

? 1. 通過Host.CreateDefaultBuilder(args): 構造IHostBuilder的默認實現HostBuilder

???在CreateHostBuilder方法內部,首先調用了Host.CreateDefaultBuilder構造了一個HostBuilder,這個我們先看下源碼,看看到底Host類內部做了什么操作:

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內部構造了一個HostBuilder,同時設置了:

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

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

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

    • 命令行參數配置

  • ? ? ?通過以下對象加載應用配置

    • appsettings.json?

    • appsettings.{Environment}.json

    • 密鑰管理器 當應用在 Development 環境中運行時

    • 環境變量

    • 命令行參數

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

    • 控制臺

    • 調試

    • EventSource

    • EventLog( Windows環境下)

  • 當環境為“開發”時,啟用范圍驗證和依賴關系驗證。

? ?以上構造完成了HostBuilder,針對ASP.NET Core應用,代碼繼續調用了HostBuilder.ConfigureWebHostDefaults方法。

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

? ?構造完成HostBuilder之后,針對ASP.NET Core應用,繼續調用了HostBuilder.ConfigureWebHostDefaults方法。這是一個ASP.NET Core的一個擴展方法:

? ?

? ?我們繼續看ConfigureWebHostDefaults擴展方法內部做了哪些事情:

? ?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

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

? ? ?代碼連接: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的構造函數GenericWebHostBuilder(buillder),將已有的HostBuilder增加了ASP.NET Core運行時設置。

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

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

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

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

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

??

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();}

  其內部實現了:

  • 前綴為 ASPNETCORE_ 的環境變量加載主機配置。

  • 將?Kestrel作為默認的Web服務器

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

  • 如果ASPNETCORE_FORWARDEDHEADERS_ENABLED=true,添加轉接頭中間件ForwardedHeaders?

  • 啟用IIS集成

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

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

? ?接下來就是主機的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:構造配置系統,初始化?IConfiguration?_hostConfiguration;

  • CreateHostingEnvironment:構建主機HostingEnvironment環境信息,包含ApplicationName、EnvironmentName、ContentRootPath等

  • CreateHostBuilderContext:創建主機Build上下文HostBuilderContext,上下文中包含:HostingEnvironment和Configuration

  • BuildAppConfiguration:構建應用程序配置

  • CreateServiceProvider:創建依賴注入服務提供程序,? 即依賴注入容器

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

? ?我們先通過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

? ? ?

? ???其實內部轉調的還是Host.StartAsync方法,在內部啟動了DI依賴注入容器中所有注冊的服務。

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

? ??

五、主機中注冊一個托管服務

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

? 自更新服務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服務容器中

// 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主機的概念、設計初衷、構建過程、啟動運行過程、服務注冊的整理和分享。

往期精彩回顧



  • 【.net core】電商平臺升級之微服務架構應用實戰

  • .Net Core微服務架構技術棧的那些事

  • Asp.Net Core 中IdentityServer4 授權中心之應用實戰

  • Asp.Net Core 中IdentityServer4 授權中心之自定義授權模式

  • Asp.Net Core 中IdentityServer4 授權流程及刷新Token

  • Asp.Net Core 中IdentityServer4 實戰之 Claim詳解

  • Asp.Net Core 中IdentityServer4 實戰之角色授權詳解

  • Asp.Net Core 中間件應用實戰中你不知道的那些事

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

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

  • ASP.NET CORE 內置的IOC解讀及使用


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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。