运行时环境
- 操作系统:Windows 11
- .NET 版本:5.0.402
- 编辑器:VS Code
示例代码
微软基于 IHostBuilder
实现了对多种应用的支持。当我们新建一个 ASP.NET Core WebAPI
项目时,默认生成的 Program.cs
文件中就会有一下代码:
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>();
});
}
建造了什么?
将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。对于应用程序来说,最复杂的莫过于应用程序本身的构建了。IHostBuilder
封装了应用程序的构建过程,让我们可以快速的开展业务(就是 Controller/Action
的编写)。
这个过程都有些什么:
- 收集素材(依赖注入);
- 读取配置;
- 初始化基础组件;
- 构建中间件管道;
- 构建
Host
承载应用; - 启动,开始监听端口;
对于应用开发人员来说,只需要按照业务的需求,注入不同的素材,就可以让程序有不同的面貌。比如使用 NLog
作为程序的日志输出组件:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog();
深入探寻
CreateDefaultBuilder
做了什么
- 将内容根目录设置为由
GetCurrentDirectory
返回的路径 - 通过以下项加载主机配置:
- 前缀为
DOTNET_
的环境变量 - 命令行参数
- 前缀为
- 通过以下对象加载应用配置:
- appsettings.json
- appsettings.{Environment}.json
- 应用在
Development
环境中运行时的用户机密 - 环境变量
- 命令行参数
- 添加以下日志记录提供程序:
- 控制台
- 调试
- EventSource
- EventLog(仅当在 Windows 上运行时)
- 当环境为“开发”时,启用范围验证和依赖关系验证
IHostBuilder
的扩展方法都在做些什么
在看各种文档的过程中,会发现其都是通过 IHostBuilder
的扩展方法来实现的。比如上面的使用 NLog 日志组件就是通过扩展方法 UseNLog()
实现的。
下面通过 UseSystemd()
来扒扒源码。首先通过名字已经知道了,这个方法是用来给 Host
提供在 Linux 里面 system 控制支持的。
public static IHostBuilder UseSystemd(this IHostBuilder hostBuilder)
{
if (SystemdHelpers.IsSystemdService())
{
hostBuilder.ConfigureServices((hostContext, services) =>
{
services.Configure<ConsoleLoggerOptions>(options =>
{
options.FormatterName = ConsoleFormatterNames.Systemd;
});
services.AddSingleton<ISystemdNotifier, SystemdNotifier>();
services.AddSingleton<IHostLifetime, SystemdLifetime>();
});
}
return hostBuilder;
}
方法里面判断了程序是不是通过 system
方式部署的,然后调用了ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate)
;看看这个方法的注释:
- 向容器内添加服务
看来只是判定符合条件之后,向容器内注入了两个服务 SystemdLifetime
和 SystemdNotifier
;
-
SystemdNotifier
是给SystemdLifetime
使用的; -
SystemdLifetime
替换了默认的IHostLifetime
,使得程序运行过程中可以响应system
的一些控制;
明白了这些,我们就可以在自己的项目中灵活的构建我们需要的应用 Host
了。
官方实现的一些 Host
-
Microsoft.Extensions.Hosting.WindowsServices
:Windows 服务的支持; -
Microsoft.Extensions.Hosting.Sstemd
:Linux 服务的支持; -
Microsoft.CommandLine.Hosting
:命令行工具的支持;