通用Host是从2.1版本被发布的,这是个非常好的想法,但是我发现关于它的各种问题,主要问题是它为类库产生了太多的工作,值得庆幸的是,3.0中的这一变化应该可以解决这些问题。
很大程度上,这个变化产生的最终结果是和你过去使用的Net Core2.X版本基本相似,但是用于配置你的app的全部配置的方法WebHost.CreateDefaultBuilder() 被替换成了两个逻辑步骤,这个两个独立的方法叫做:
Host.CreateDefaultBuilder() ,负责配置你的app配置、日志以及依赖注入容器
IHostBuilder.ConfigureWebHostDefaults() ,负责为经典的Asp Net Core 应用添加所需要的所有东西,比如:配置Kestrel和使用一个 Startup.cs用于配置你的DI容器和中间件管道
通用Host builder正如我之前说的那样,通用Host为Asp Net core 3.0的构建提供了基础。它同样也提供了你先前在Asp Net core应用中使用的基础性的Microsoft.Extensions.* 元素,比如:日志、配置和依赖注入。
下面的代码是一个简化版本的 Host.CreateDefaultBuilder() 方法。它和2.X版本的 WebHost.CreateDefaultBuilder() 作用一样。但是我会简短说一下值得关注的变化。
public static IHostBuilder CreateDefaultBuilder(string[] args) { var builder = new HostBuilder(); builder.UseContentRoot(Directory.GetCurrentDirectory()); builder.ConfigureHostConfiguration(config => { // Uses DOTNET_ environment variables and command line args }); builder.ConfigureAppConfiguration((hostingContext, config) => { // JSON files, User secrets, environment variables and command line arguments }) .ConfigureLogging((hostingContext, logging) => { // Adds loggers for console, debug, event source, and EventLog (Windows only) }) .UseDefaultServiceProvider((context, options) => { // Configures DI provider validation }); return builder; }简而言之,这个的不同点如下:
Hosting配置使用以 DOTNET_ 为前缀的环境变量
Hosting配置使用命令行变量
增加了 EventSourceLogger 和 EventLogLogger 日志提供者
可以选择使用ServiceProvider验证功能
没有关于Web Hosting 的特定配置
第一个有意思的地方就是Host配置是如何设置的。对于Web Host而言,默认使用以 ASPNETCORE_ 为前缀的环境变量作为配置。所以设置ASPNETCORE_ENVIRONMENT 环境变量将会设置 Environment 配置的值。对于 通用Host来说,这个前缀现在是DOTNET_ ,和传给应用运行时的任意命令行参数。
这个host配置起的作用好比是决定你的应用运行在什么的主机环境,host配置与你应用配置(与IOptions接口一起使用的配置)是隔离开来的。
配置你的app设置的方法 ConfigureAppConfiguration() 与2.X相比是没有变化的,所以它仍然使用appsettings.json文件、appsetting.ENV.json风格文件、用户机密数据、环境变量以及命令行参数。
通用Host的日志部分已经在3.0进行了扩展。它仍旧通过你的app配置来,以及添加控制台和Debug日志提供者。然而它同样也添加来事件源日志提供者,事件源日志用于和像windows上的ETW、Linux上的LTTng这样的系统日志进行交互。另外,添加一个,只能在windows才会把日志信息写入Windows Event Log。
最后,当你的app运行在开发环境时,通用Host配置依赖注入容器的目的是它会验证范围(Scopes),这个操作和2.X一样。这旨在抓取捕获的依赖关系的实例,在这些实例中,你将一个范围(Scopes)的服务注入到单例服务中。在3.0中,通用Host通用能启动 ValidateOnBuild 的功能,我将会在下一篇博客中讲到。
通用Host一个关键的点是他是通用的,它和Asp Net core 或者Http 工作负载没有任何关联。你可以像经典的Asp Net core 应用一样把通用Host作为你的控制台app或者其他长运行服务的基石。在3.0中你只需要在你的Asp net core 层的顶部增加一个 ConfigureWebHostDefaults() 就可以搞定。
***
这篇博客已经很长了,所以在这里我不想深入挖掘太多的细节,但是,对于添加Asp Net core “层”到 通用Host上面而言,ConfigureWebHostDefaults扩展方法是非常有用的。就简单层面而言,调用这个方法会使Kestrel web 服务添加到这个host上面,但是这里面也存在了大量的。下面是关于这个方法提供,(包含了GenericWebHostBuilder提供的特性)
为Host 配置添加了 ASPNETCORE_ 前缀的环境变量(除了 DOTNET_ 前缀的变量和命令行参数)
增加了 GenericWebHostService ,这是一个IHostedService的实现,它通常运行在Asp Net core服务上,这是一个主要的特性,这个特性为Asp Net core 复用通用Host提供了可能。
增加了一个额外的app配置源,在RazorUI类库中,这个 StaticWebAssetsLoader 与静态文件(css/js)共同发挥作用。
使用默认Kestrel配置(与2.X一样)
增加 HostFilteringStartupFilter (和2.0一样)
增加 ForwardedHeadersStartupFilter ,如果 ForwardedHeaders_Enabled 配置值是true,例如,如果ASPNETCORE_FORWARDEDHEADERS_ENABLED 环境变量的值是true。
启动windows上的IIS集成
增加一个到DI容器中