在.NET Core中,Host负责应用程序的启动和生命周期管理。除此之外,在Host中还可以设置日志(Logging)、配置(Configuration)和依赖关系注入(Dependency Injection)等。Host将一个常规的控制台应用程序(Console Application)变成了一个可以长时间运行的服务(Long-running Service)。

Hosting History

在.NET Core中,有以下2个Host:

  • .NET Generic Host(简称 Generic Host)

  • ASP.NET Core Web Host(简称 Web Host)

要了解它们之间的区别与联系,我们需要从.NET Core的发展历程中寻找答案。

微软在2016年6月发布了.NET Core 1.0。.NET Core是一个开放的、支持跨平台的框架,它与.NET Framework有着显著的不同。在这之后微软又陆续发布了.NET Core 1.1.NET Core 2.0.NET Core 2.1.NET Core 2.2.NET Core 3.0.NET Core 3.1

Web Host在.NET Core 1.0中被引入,它被用于配置并启动KestrelWeb服务器,在指定的端口上监听HTTP请求。Web Host正如它的名称所言,只用于Host ASP.NET Core Web Application。

Generic Host在.NET Core 2.1中被引入,但它只被用于non-HTTP的场景,例如hosted services/worker services。此时你仍需要使用Web Host来Host ASP.NET Core Web Application。这带来了一定的混淆和麻烦,很多相近的类被引入。

IWebHost 与 IHost,IWebHostBuilder与IHostBuilder

Interface Namespace Default Implementation Git Repo Source Code
IWebHost Microsoft.AspNetCore.Hosting WebHost https://github.com/dotnet/aspnetcore src/Hosting/Hosting/src/Internal/WebHost.cs
IHost Microsoft.Extensions.Hosting Host https://github.com/dotnet/runtime src/libraries/Microsoft.Extensions.Hosting/src/Internal/Host.cs
IWebHostBuilder Microsoft.AspNetCore.Hosting WebHostBuilder https://github.com/dotnet/aspnetcore src/Hosting/Hosting/src/WebHostBuilder.cs
IHostBuilder Microsoft.Extensions.Hosting HostBuilder https://github.com/dotnet/runtime src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs

还有与这些接口相关的静态辅助类:

Class Namespace Git Repo Source Code
WebHost Microsoft.AspNetCore https://github.com/dotnet/aspnetcore src/DefaultBuilder/src/WebHost.cs
Host Microsoft.Extensions.Hosting https://github.com/dotnet/runtime src/libraries/Microsoft.Extensions.Hosting/src/Host.cs

我们在Program.cs文件中一般都是用这两个静态辅助类来创建IWebHost或IHost的具体实例,进而启动应用程序。

IHostingEnvironment vs IHostEnvironment vs IWebHostEnvironment

这几个接口是不是傻傻分不清?这其实充分说明了微软在主导.NET Core的开发过程中存在着管理和命名的混乱。这也难免,毕竟这么大的项目,而且代码库也是各管各的。

首先IHostingEnvironment存在于2个不同的命名空间中,虽然接口内容大致相同,但却是互不兼容的——它们之间没有继承关系。

Interface Namespace Git Repo Source Code
IHostingEnvironment Microsoft.AspNetCore.Hosting https://github.com/dotnet/aspnetcore src/Hosting/Abstractions/src/IHostingEnvironment.cs
IHostingEnvironment Microsoft.Extensions.Hosting https://github.com/dotnet/runtime src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/IHostingEnvironment.cs

从.NET Core 3.0起,这两个接口都被标记为obsolete,取而代之的分别是IWebHostEnvironment 与 IHostEnvironment。它们依然存在于不同的命名空间中,但它们之间有了继承关系。

Interface Namespace Git Repo Source Code
IWebHostEnvironment Microsoft.AspNetCore.Hosting https://github.com/dotnet/aspnetcore src/Hosting/Abstractions/src/IWebHostEnvironment.cs
IHostEnvironment Microsoft.Extensions.Hosting https://github.com/dotnet/runtime src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/IHostEnvironment.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace Microsoft.AspNetCore.Hosting
{public interface IWebHostEnvironment : IHostEnvironment{string WebRootPath { get; set; }IFileProvider WebRootFileProvider { get; set; }}
}namespace Microsoft.Extensions.Hosting
{public interface IHostEnvironment{string EnvironmentName { get; set; }string ApplicationName { get; set; }string ContentRootPath { get; set; }IFileProvider ContentRootFileProvider { get; set; }}
}

这样的设计就很合理,也减少了重复。它们各自的默认实现也基本相同。

Default Implementation Namespace Git Repo Source Code
HostingEnvironment Microsoft.AspNetCore.Hosting https://github.com/dotnet/aspnetcore src/Hosting/Hosting/src/Internal/HostingEnvironment.cs
HostingEnvironment Microsoft.Extensions.Hosting.Internal https://github.com/dotnet src/libraries/Microsoft.Extensions.Hosting/src/Internal/HostingEnvironment.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace Microsoft.AspNetCore.Hosting
{internal class HostingEnvironment : IHostingEnvironment, Extensions.Hosting.IHostingEnvironment,IWebHostEnvironment{public string EnvironmentName { get; set; } = Extensions.Hosting.Environments.Production;public string ApplicationName { get; set; }public string WebRootPath { get; set; }public IFileProvider WebRootFileProvider { get; set; }public string ContentRootPath { get; set; }public IFileProvider ContentRootFileProvider { get; set; }}
}namespace Microsoft.Extensions.Hosting.Internal
{public class HostingEnvironment : IHostingEnvironment, IHostEnvironment{public string EnvironmentName { get; set; }public string ApplicationName { get; set; }public string ContentRootPath { get; set; }public IFileProvider ContentRootFileProvider { get; set; }}
}

Generic Host 取代 Web Host

时间来到了.NET Core 3.0发布。微软重构了Generic Host,使之成为一个真正的通用的Host——可同时运行Worker Services和Web Applications。这大大简化了Host的模型及相关的类,开发者理解和使用起来更加容易了。

图片来自PluralSight课程

小结

  • 尽可能地使用IHostEnvironment

  • 官方不建议在.NET Core 3.0及以上的版本中使用Web Host

  • 对于ASP.NET Core Web Application来说,Kestrel Web Server被包装在GenericWebHostService中被Generic Host初始化并启动

微软于2020年11月发布了.NET 5.NET 5是.NET Core的下一个版本,被描述为.NET统一之旅中的第一个版本,它是为了使更多的开发人员能够将.NET框架代码和应用迁移到.NET 5。该平台将来自.NET Framework、.NET Core和Mono的代码组合在一起,为所有现代.NET应用提供一个单一的平台。本文所讨论的.NET Generic Host同样适用于.NET 5

CreateDefaultBuilder与ConfigureWebHostDefaults

一般情况下,我们使用静态辅助类Host中的CreateDefaultBuilder方法来创建IHostBuilder的实例。对于ASP.NET Core Web Application,我们还会调用ConfigureWebHostDefaults方法。我们需要了解这两个方法到底做了哪些默认的设置,以便减少不必要、多余的设置。

CreateDefaultBuilder 方法

  • 将内容根目录设置为由 GetCurrentDirectory 返回的路径

  • 通过以下项加载主机配置:

    • 前缀为 DOTNET_ 的环境变量

    • 命令行参数

  • 通过以下项加载应用配置:

    • appsettings.json

    • appsettings.{Environment}.json

    • 在 Development 环境中运行时的用户机密配置信息(secrets.json)

    • 环境变量

    • 命令行参数

  • 添加以下日志提供程序:

    • 控制台

    • 调试

    • EventSource

    • EventLog(仅当在 Windows 上运行时)

  • 在 Development 环境中,启用范围验证和依赖关系验证

图片来自PluralSight课程

ConfigureWebHostDefaults 方法

  • 从前缀为 ASPNETCORE_ 的环境变量加载主机配置。

  • 使用应用的托管配置提供程序将 Kestrel 服务器设置为 web 服务器并对其进行配置。

  • 如果 ASPNETCORE_FORWARDEDHEADERS_ENABLED 等于 true,则添加转接头中间件(ForwardedHeadersStartupFilter)。

  • 添加 IIS 集成。

推荐阅读源代码了解更多的实现细节

  • CreateDefaultBuilder

    • ConfigureDefaults

  • ConfigureWebHostDefaults

    • GenericWebHostBuilder

    • ConfigureWebDefaults

    • ConfigureWebHost

Generic Host 的启动与停止

启动

Generic Host 的启动步骤如下:

  1. Program.cs文件中,通过CreateDefaultBuilder构建一个IHost的实例

  2. 调用IHost上的静态扩展方法Run或RunAsync,这会间接调用到IHostStartAsync方法

  3. IHost的StartAsync方法则会遍历所有注册的IHostedService,调用它的StartAsync方法

  4. IHost上的静态扩展方法[Run或RunAsync]会调用另一个扩展方法——WaitForShutdownAsync,等待程序结束的信号

图片来自PluralSight课程
.NET Core 应用程序运行后会创建名为.NET Host(dotnet.exe)的后台进程。

停止

Generic Host 的停止步骤如下:

  1. 用户使用Ctrl + C或者应用程序使用代码来发出程序结束的信号

  2. IHost的StopAsync方法在WaitForShutdownAsync中被调用

  3. 所有注册的IHostedServiceStopAsync方法被调用

  4. 应用程序退出

图片来自PluralSight课程
需要指出的是,IHostedService的注册顺序是非常重要的,启动的时候是按注册顺序,停止的时候则是倒序。

其它的Host

在Windows操作系统中,你还会看到很多其它的Host。

Console Window Host(conhost.exe)

Console Window Host, 即命令行程序的宿主进程。典型的命令行程序有cmd.exe、nslookup.exe等。Console Window Host负责绘制命令行程序的图形化窗口,管理输入缓冲区屏幕缓冲区

Service Host(svchost.exe)

Service Host是一个共有的宿主进程的名称,它用来运行DLL文件中的服务,特别是很多系统服务。为了使这些服务之间保持隔离,减少相互影响导致的程序错误,系统会运行很多个Service Host的进程实例。你可以使用Process Explorer这个工具,通过Command Line列来区分它们。

DLL Host(dllhost.exe)

DLL Host程序又称为COM Surrogate,它是COM组件的宿主进程。COM(Component Object Model,组件对象模型)是微软于1993年提出的一种软件开发技术,它定义了组件对象进行交互的二进制接口标准。COM组件大多以动态链接库(DLL)的形式发布,DLL Host(dllhost.exe)则正是加载这些COM组件的宿主程序。与Service Host类似,系统会运行很多个DLL Host的进程实例。你可以使用Process Explorer这个工具,通过Command Line列来区分它们。

参考资料

  • ASP.NET Core Web Host

  • .NET Generic Host in ASP.NET Core

  • Building ASP.NET Core Hosted Services and .NET Core Worker Services

  • Introducing .NET Core

  • Announcing .NET Core 1.0

  • Announcing .NET 5.0

  • Understanding .NET Generic Host Model

  • Generic Host Builder in ASP .NET Core 3.1

  • Changes to Service Host grouping in Windows 10

Hosting in .NET Core相关推荐

  1. ASP.NET Core 中文文档 第三章 原理(12)托管

    原文:Hosting 作者:Steve Smith 翻译:娄宇(Lyrics) 校对:何镇汐.许登洋(Seay) 为了运行 ASP.NET Core 应用程序,你需要使用 WebHostBuilder ...

  2. ASP.NET Core 认证与授权[2]:Cookie认证

    ASP.NET Core 认证与授权[2]:Cookie认证 原文:ASP.NET Core 认证与授权[2]:Cookie认证 由于HTTP协议是无状态的,但对于认证来说,必然要通过一种机制来保存用 ...

  3. ASP.NET Core 运行原理解剖[5]:Authentication

    在现代应用程序中,认证已不再是简单的将用户凭证保存在浏览器中,而要适应多种场景,如App,WebAPI,第三方登录等等.在 ASP.NET 4.x 时代的Windows认证和Forms认证已无法满足现 ...

  4. ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界

    本系列文章从源码分析的角度来探索 ASP.NET Core 的运行原理,分为以下几个章节: ASP.NET Core 运行原理解剖[1]:Hosting ASP.NET Core 运行原理解剖[2]: ...

  5. ASP.NET Core 运行原理解剖[3]:Middleware-请求管道的构成

    在 ASP.NET 中,我们知道,它有一个面向切面的请求管道,有19个主要的事件构成,能够让我们进行灵活的扩展.通常是在 web.config 中通过注册 HttpModule 来实现对请求管道事件监 ...

  6. NET CORE Learning

    ASP.NET Core 基础教程 https://www.cnblogs.com/lonelyxmas/tag/ASP.NET%20Core%20%E5%9F%BA%E7%A1%80%E6%95%9 ...

  7. windows server 2008 R2 x64 部署.net core 3.1项目

    1.安装 vc_redist.x64 https://www.microsoft.com/en-us/download/details.aspx?id=48145 2.安装Windows Hostin ...

  8. .NET Core 3.0 正式公布:新特性详细解读

    点击蓝字"dotNET匠人"关注我哟 加个"星标★",每日 7:15,好文必达! 作者丨Richard Lander 译者丨核子可乐 策划丨赵钰莹 近日,.NE ...

  9. Windows IIS 环境部署 .NET Core 语言文件 SSL证书 HTTPS协议

    Azure 应用服务和 IIS 上 ASP.NET Core 的常见错误参考 .NET Core 应用程序发布概述[发布独立应用] .NET Core 应用程序发布概述[发布依赖于运行时的应用] Do ...

最新文章

  1. Linq let Concat
  2. tp5某个字段相同的数据只取一次_多维分析数据仓库建设建议-面向主题的建模...
  3. rooibos茶中单宁酸研究
  4. python利用matplotlib做饼图_python利用matplotlib库绘制饼图的方法示例
  5. matlab直方图显示,控制分类直方图的显示
  6. bat自动输入密码登录_【第7期】Teamcenter自动登录改进,对portal.bat中登录密码加密...
  7. 关于if else 和 switch 的区别 究竟哪个更快
  8. ThinkPHP的pathinfo模式、路径访问模式及URL重写
  9. 工作没做好,别人指出时最好装聋作哑
  10. Python实现LBP算法
  11. 算法竞赛入门经典训练指南 pdf
  12. 华为手机怎么安装Google
  13. Pyqt通过鼠标滚轮进行缩放界面
  14. winedit注册码
  15. Android中自定义注解处理器
  16. 快速校验 input内容规则
  17. 【MySQL 8.0 OCP 1Z0-908认证考试】题库精讲--第三讲mysql8.0安装配置升级(下)
  18. 【ChatGPT初体验与Android的集成使用】
  19. 麒麟子Javascript游戏编程零基础教程一:序言
  20. 17未央,我备一曲离殇

热门文章

  1. Plsql运行mysql脚本_oracle中PLSQL语句
  2. 洛谷P2463 Sandy的卡片【后缀数组】【二分】
  3. Shell脚本之sed的使用
  4. 2011目标 及 总结
  5. mysql interval 3 day_Mysql之INTERVAL与DATE_SUB与EXTRACT函数的使用
  6. powershell 入门_使用PowerShell入门的5个Cmdlet
  7. safari 获取视频流_如何在Safari中将RSS feed和社交媒体合并为一个流
  8. 管理员获得所有权_在Windows 7中获得注册表项的所有权
  9. javascript权威指南--学习笔记
  10. 软件工程—团队作业1