ASP.NET Core 5.0之默认主机Host.CreateDefaultBuilder
通过Rider调试的方式看了下ASP.NET Core 5.0的Web API默认项目,重点关注Host.CreateDefaultBuilder(args)中的执行过程,主要包括主机配置、应用程序配置、日志配置和依赖注入配置这4个部分。由于水平和篇幅有限,先整体理解、建立框架,后面再逐步细化,对每个配置部分再详细拆解。
一.创建默认主机Host.CreateDefaultBuilder
1.创建主机构建器CreateHostBuilder(args)
基于ASP.NET Core 5.0构建的Web API项目的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>();
});
}
2.创建默认构建器Host.CreateDefaultBuilder(args)
本文重点讲解下Host.CreateDefaultBuilder(args)的执行过程,Microsoft.Extensions.Hosting.Host是一个静态类,包含2个方法:
public static IHostBuilder CreateDefaultBuilder() =>CreateDefaultBuilder(args: null);
public static IHostBuilder CreateDefaultBuilder(string[] args);
上面的方法最终调用的还是下面的方法,下面的方法主要包括几个部分:主机配置ConfigureHostConfiguration,应用程序配置ConfigureAppConfiguration,日志配置ConfigureLogging,依赖注入配置UseDefaultServiceProvider。
二.主机配置ConfigureHostConfiguration
主机配置ConfigureHostConfiguration相关源码如下:
builder.UseContentRoot(Directory.GetCurrentDirectory());
builder.ConfigureHostConfiguration(config =>
{
config.AddEnvironmentVariables(prefix: "DOTNET_");
if (args != null)
{
config.AddCommandLine(args);
}
});
1.内存配置源
Directory.GetCurrentDirectory()
当前目录指的就是D:\SoftwareProject\C#Program\WebApplication3\WebApplication3
。
2.环境变量配置源
config.AddEnvironmentVariables(prefix: "DOTNET_")
添加了前缀为DOTNET_
的环境变量。
3.命令行配置源
最开始认为参数args为null,经过调试发现args的值string[0],并且args != null
,所以会有命令行配置源CommandLineConfigurationSource。
三.应用程序配置ConfigureAppConfiguration
应用程序配置ConfigureAppConfiguration相关源码如下:
builder.ConfigureAppConfiguration((hostingContext, config) =>
{
IHostEnvironment env = hostingContext.HostingEnvironment;
bool reloadOnChange = hostingContext.Configuration.GetValue("hostBuilder:reloadConfigOnChange", defaultValue: true);
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange).AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);
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);
}
})
1.程序运行的主机环境
hostingContext.HostingEnvironment表示运行程序的主机环境,比如开发环境或者生产环境。IHostEnvironment接口的数据结构为:
public interface IHostEnvironment
{
// Development
string EnvironmentName { get; set; }
// WebApplication3
string ApplicationName { get; set; }
// D:\SoftwareProject\C#Program\WebApplication3\WebApplication3
string ContentRootPath { get; set; }
// PhysicalFileProvider
IFileProvider ContentRootFileProvider { get; set; }
}
2.加载json配置文件
接下来就是通过AddJsonFile()来添加配置文件了,如下所示:
(1)Path(string):json文件的相对路径位置。
(2)Optional(bool):指定文件是否是必须的,如果为false,那么如果找不到文件就会抛出文件找不到异常。
(3)ReloadOnchange(bool):如果为true,那么当改变配置文件,应用程序也会随之更改而无需重启。 在该项目中总共有2个配置文件,分别是appsettings.json和appsettings.Development.json。
3.添加用户秘钥配置源
config.AddUserSecrets(appAssembly, optional: true)
主要是在开发的过程中,用来保护配置文件中的敏感数据的,比如密码等。因为平时在开发中很少使用,所以在此不做深入讨论,如果感兴趣可参考[3]。
四.日志配置ConfigureLogging
日志配置ConfigureLogging相关源码如下:
.ConfigureLogging((hostingContext, logging) =>
{
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isWindows)
{
// Default the EventLogLoggerProvider to warning or above
logging.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 machines
logging.AddEventLog();
}
logging.Configure(options =>
{
options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
| ActivityTrackingOptions.TraceId
| ActivityTrackingOptions.ParentId;
});
})
1.Windows日志级别
从上述代码中可以看到是LogLevel.Warning
及以上。
2.日志的配置
ILoggerProvider不同的实现方式有:ConsoleLoggerProvider
,DebugLoggerProvider
,EventSourceLoggerProvider
,EventLogLoggerProvider
,TraceSourceLoggerProvider
,自定义
。下面是日志配置涉及的相关代码:
logging.AddConsole(); //将日志输出到控制台
logging.AddDebug(); //将日志输出到调试窗口
logging.AddEventSourceLogger();
logging.AddEventLog();
说明:这一部分详细的日志分析可以参考[6]。
3.ActivityTrackingOptions
public enum ActivityTrackingOptions
{
None = 0, //No traces will be included in the log
SpanId = 1, //The record will contain the Span identifier
TraceId = 2, //The record will contain the tracking identifier
ParentId = 4, //The record will contain the parent identifier
TraceState = 8, //The record will contain the tracking status
TraceFlags = 16, //The log will contain trace flags
}
在最新的.NET 7 Preview6中又增加了Tags(32)和Baggage(64)。
五.依赖注入配置UseDefaultServiceProvider
依赖注入配置UseDefaultServiceProvider相关源码如下:
.UseDefaultServiceProvider((context, options) =>
{
bool isDevelopment = context.HostingEnvironment.IsDevelopment();
options.ValidateScopes = isDevelopment;
options.ValidateOnBuild = isDevelopment;
});
UseDefaultServiceProvider主要是设置默认的依赖注入容器。
鸣谢:
https://mp.weixin.qq.com/s/6MYycyaYZzdGLAR947dHcg
参考文献:
[1].NET Source Browser:https://source.dot.net/
[2]Safe storage of app secrets in development in ASP.NET Core:https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-6.0&tabs=windows
[3]认识ASP.NET Core/Host及其配置解析:https://zhuanlan.zhihu.com/p/343312339
[4]源码解析.Net中Host主机的构建过程:https://www.cnblogs.com/snailZz/p/15240616.html
[5].NET Core通用Host源码分析:https://www.cnblogs.com/yingbiaowang/p/15048495.html
[6]基于.NetCore3.1系列--日志记录之日志配置揭秘:https://www.cnblogs.com/i3yuan/p/13411793.html
[7]基于.NetCore3.1系列--日志记录之日志核心要素揭秘:https://www.cnblogs.com/i3yuan/p/13442509.html
[8].NET5中Host.CreateDefaultBuilder(args)详解:https://blog.csdn.net/qbc12345678/article/details/122983855
[9]ASP.NET启动和运行机制:https://www.jianshu.com/p/59cfaba4e2cb
[10]ASP.Net Core解读通用主机和托管服务:https://www.cnblogs.com/qtiger/p/12976207.html
ASP.NET Core 5.0之默认主机Host.CreateDefaultBuilder的更多相关文章
- ASP .Net Core 2.0 修改默认端口
ASP .Net Core 的默认端口是5000,如果想在同一台服务器上运行多个实例,就不能都监听5000端口了,需要每一个实例都监听不同的端口.当然,如果您正在使用IIS或者Jexus来托管,可以不 ...
- 探索 ASP.Net Core 3.0系列五:引入IHostLifetime并弄清Generic Host启动交互
前言:在本文中,我将介绍如何在通用主机之上重新构建ASP.NET Core 3.0,以及由此带来的一些好处. 同时也展示了3.0中引入新的抽象类IHostLifetime,并描述了它在管理应用程序(尤 ...
- ASP.NET Core 2.0升级到3.0的变化和问题
前言 在.NET Core 2.0发布的时候,博主也趁热使用ASP.NET Core 2.0写了一个独立的博客网站,现如今恰逢.NET Core 3.0发布之际,于是将该网站进行了升级. 下面就记录升 ...
- ASP.NET Core 5.0中的Host.CreateDefaultBuilder执行过程
通过Rider调试的方式看了下ASP.NET Core 5.0的Web API默认项目,重点关注Host.CreateDefaultBuilder(args)中的执行过程,主要包括主机配置.应用程 ...
- #ASP.NET Core 1.0 Key Features
Cross platform support and flexible runtime engine(跨平台支持和灵活的运行时引擎) ASP.NET Core 1.0 offers support f ...
- 升级 ASP.NET Core 3.0 设置 JSON 返回 PascalCase 格式与 SignalR 问题
由于一些 JS 组件要求 JSON 格式是 PascalCase 格式,新版本 ASP.NET Core 3.0 中默认移除了 Newtonsoft.Json ,使用了微软自己实现的 System.T ...
- 将 ASP.NET Core 1.0 应用作为 docker 镜像发布 (Linux版)
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...
- .Net Core 2.0生态(3):ASP.NET Core 2.0 特性介绍和使用指南
ASP.NET Core 2.0 发布日期:2017年8月14日 ASP.NET团队宣布ASP.NET Core 2.0正式发布,发布Visual Studio 2017 15.3支持ASP.NET ...
- 为什么你需要将代码迁移到ASP.NET Core 2.0?
随着 .NET Core 2.0 的发布,.NET 开源跨平台迎来了新的时代.开发者们可以选择使用命令行.个人喜好的文本编辑器.Visual Studio 2017 15.3 和 Visual Stu ...
- Ubuntu & Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践
相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...
随机推荐
- jemter 分布式压测
1.测试机搭建 首选 压力机A,压力机B,压力机C, 压力机A作为控制台 压力机B,压力机C作为分布式的测试机 压力机Aip:172.16.23.69, 压力机Bip:192.168.184.128 ...
- pyspark 结构化数据开发实例
什么是SPARK? 1. 先进的大数据分布式编程和计算框架 2. 替换Hadoop 中的MR计算引擎. 3. 内存分布式计算:运行数度快 4. 可以使用不同的语言编程(java,scala,r 和py ...
- FCOS网络(free anchor)
FCOS FCOS网络解析 FPN输出多个特征图,然后如何处理这些特征图? [问题]"特征图相对原图的步距是s"是个什么东西
- css3中-webkit是什么意思
在CSS样式中很多样式名前缀都带有'-webkit-',但在CSS提供的API中查询不到这些样式名. 原因:CSS3中新增了一些属性,针对不同的浏览器,规定其内核名称让它们可以对这些新增属性进行解析. ...
- 【C++】之前学习C++没有注意到的点或者学到了冷知识(待补充)
1.string和c_str() string str = "hello"; const char* cstr = str.c_str(); str = "yep,i m ...
- 《Rust权威指南》学习笔记——4. 认识所有权
Rust权威指南学习笔记--认识所有权 什么是所有权 1. 所有权规则 Rust中的每一个值都有一个对应的变量作为它的所有者. 在同一时间内,值有且仅有一个所有者. 当所有者离开自己的作用域时,它持有 ...
- 生成虚拟mac地址通过dhcp获取ip,耗尽dhco地址池
平台:kali 软件:dhcpstarv 命令 dhcpstarv -i 网卡名称 -e 本机IP 查看dhcp服务器已经分发的地址 cat /tmp/dhcp.leases
- oracle之如何获取执行计划方法
1.什么是执行计划 为了执行sql语句,Oracle在内部必须实现许多步骤,这些步骤可能是从数据库中物理检索数据行,或者用某种方法来准备数据行等,接着Oracle会按照一定的顺序一次执行这些步骤,最后 ...
- Chrome上谷歌翻译不能使用问题
# 修改hosts文件(hosts文件位于 C:\Windows\System32\drivers\etc) 142.250.107.90 http://translate.googleapis.co ...
- ESXi 基础安全加强(ing...)
# 查看防火墙规则esxcli network firewall ruleset allowedip list # 允许指定ip使用web服务和客户端访问[root@localhost:~] esxc ...