Asp.net Core WebHost寄宿在Host上
1 直接上结论:
那就是asp.net core Web主机(即Web Host) 是寄宿在Host(也叫做Generic Host,泛型主机)上的。主机寄宿是靠实现IHostedService接口达到的,然后调用AddHostedService()方法达到的,类似下面这样:
// GenericWebHostBuilder类的构造函数会调用下面这句话
services.AddHostedService<GenericWebHostService>();
这就是通过依赖注入,往Host上注入了Web服务。
2 分析源码
public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}
如果不调用ConfigureWebHostDefaults(…)方法,就不会有Web服务,因此Web服务是通过调用ConfigureWebHostDefaults()方法而来的,这个方法在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,/// configure the <see cref="IWebHostEnvironment.WebRootFileProvider"/> to map static web assets when <see cref="IHostEnvironment.EnvironmentName"/> is 'Development' using the entry assembly,/// 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);});}}
}
从上面源码可以发现ConfigureWebHostDefaults()继续调用builder.ConfigureWebHost()方法,那么我们继续看一下ConfigureWebHost()方法都有些什么,这个方法在
GenericHostWebHostBuilderExtensions.cs文件里定义:
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Internal;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);return builder;}}
}
现在,我们可以发现终于new了一个webhostBuilder这样的东西,从名字里可以猜测到,它肯定是用于建造web host的,那么具体是怎么嵌入Host的呢,这就需要进一步查看GenericWebHostBuilder类的构造函数,由于这个构造函数代码很长,这里就不贴了,我们可以在GenericWebHostBuilder类的构造函数发现文章开头的AddHostedService()这样的代码,这就是将Web Host注入到Generic Host当中,因此Web Host是由Generic Host启动的,Host是宿主,WebHost只是个"寄生虫"。
3 结个尾
这里多说一句,我们自己也可以建造自己的主机(host)寄宿到Generic Host上,但是不是什么玩意都可以寄宿的,寄宿有规范的,这个规范就是得是实现IHostedService接口的主机才行,因此,我们很容易猜想的到GenericWebHostService类就是Web Host实现了IHostedService的一个类,事实也是如此。
4 回顾下微软原话
主机(Generic Host)定义
主机(Generic Host)是封装应用资源的对象,例如:
- 依赖关系注入 (DI)
- Logging
- Configuration
- IHostedService 实现
当主机(Generic Host)启动时,它将对在托管服务的服务容器集合中注册的 IHostedService 的每个实现调用 IHostedService.StartAsync。 在 web 应用中,其中一个 IHostedService 实现是启动 HTTP 服务器实现的 web 服务。