.net core 源码分析(4) 启动过程-InitializeHostingEnvironment
本篇主要讲述HostBuilder.Build()的第二阶段 InitializeHostingEnvironment
public partial class HostBuilder : IHostBuilder { private const string HostBuildingDiagnosticListenerName = "Microsoft.Extensions.Hosting"; private const string HostBuildingEventName = "HostBuilding"; private const string HostBuiltEventName = "HostBuilt"; private readonly List<Action<IConfigurationBuilder>> _configureHostConfigActions = new List<Action<IConfigurationBuilder>>(); private readonly List<Action<HostBuilderContext, IConfigurationBuilder>> _configureAppConfigActions = new List<Action<HostBuilderContext, IConfigurationBuilder>>(); private readonly List<Action<HostBuilderContext, IServiceCollection>> _configureServicesActions = new List<Action<HostBuilderContext, IServiceCollection>>(); private readonly List<IConfigureContainerAdapter> _configureContainerActions = new List<IConfigureContainerAdapter>(); private IServiceFactoryAdapter _serviceProviderFactory; private bool _hostBuilt; //第一阶段被创建 private IConfiguration? _hostConfiguration; //下方二个私有对象将在第二阶段被创建 private HostingEnvironment? _hostingEnvironment; private PhysicalFileProvider? _defaultProvider; }
HostingEnvironment 类型继承 IHostingEnvironment接口和IWebHostEnvironment接口,来看一下二者有什么区别
public interface IHostingEnvironment { /// <summary> /// 获取或设置环境名称。主机会自动将此属性设置为 "ASPNETCORE_ENVIRONMENT" 环境变量的值, /// 或其他配置源中指定的 "environment" 值。 /// </summary> string EnvironmentName { get; set; } /// <summary> /// 获取或设置应用程序名称。此属性由主机自动设置为包含应用程序入口点的程序集名称。 /// </summary> string ApplicationName { get; set; } /// <summary> /// 获取或设置包含可被 Web 服务的应用程序内容文件的目录的绝对路径。 /// </summary> string WebRootPath { get; set; } /// <summary> /// 获取或设置指向 <see cref="WebRootPath"/> 的 <see cref="IFileProvider"/>。 /// </summary> IFileProvider WebRootFileProvider { get; set; } /// <summary> /// 获取或设置包含应用程序内容文件的目录的绝对路径。 /// </summary> string ContentRootPath { get; set; } /// <summary> /// 获取或设置指向 <see cref="ContentRootPath"/> 的 <see cref="IFileProvider"/>。 /// </summary> IFileProvider ContentRootFileProvider { get; set; } }
IWebHostEnvironment接口
/// <summary> /// 提供有关应用程序运行的 Web 主机环境的信息。 /// </summary> public interface IWebHostEnvironment : IHostEnvironment { /// <summary> /// 获取或设置包含可被 Web 服务器访问的应用程序内容文件的目录的绝对路径。 /// 默认为 'wwwroot' 子文件夹。 /// </summary> string WebRootPath { get; set; } /// <summary> /// 获取或设置指向 <see cref="WebRootPath"/> 的 <see cref="IFileProvider"/>。 /// 默认为引用 'wwwroot' 子文件夹中的文件。 /// </summary> IFileProvider WebRootFileProvider { get; set; } }
初始化过程
[MemberNotNull(nameof(_defaultProvider))] [MemberNotNull(nameof(_hostingEnvironment))] private void InitializeHostingEnvironment() { // 使用 CreateHostingEnvironment 方法创建并初始化 _hostingEnvironment 和 _defaultProvider。 // _hostConfiguration 在HostBuilder.Build()中的第一阶段已经被创建。 (_hostingEnvironment, _defaultProvider) = CreateHostingEnvironment(_hostConfiguration!); } // 这个方法用于创建和配置 HostingEnvironment 对象及其关联的 PhysicalFileProvider。 // 接受 IConfiguration 类型的 hostConfiguration 参数,用于读取配置值。 internal static (HostingEnvironment, PhysicalFileProvider) CreateHostingEnvironment(IConfiguration hostConfiguration) { // 创建 HostingEnvironment 对象,并根据 hostConfiguration 配置其 EnvironmentName 和 ContentRootPath 属性。 var hostingEnvironment = new HostingEnvironment() { //如果用户未显示配置运行环境则默认为Production。 EnvironmentName = hostConfiguration[HostDefaults.EnvironmentKey] ?? Environments.Production, ContentRootPath = ResolveContentRootPath(hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; // 尝试从 hostConfiguration 中获取 ApplicationName,如果获取不到则从当前程序的入口程序集获取其名称。 string? applicationName = hostConfiguration[HostDefaults.ApplicationKey]; if (string.IsNullOrEmpty(applicationName)) { applicationName = Assembly.GetEntryAssembly()?.GetName().Name; } // 如果成功获取到 applicationName,则将其设置到 HostingEnvironment 对象中。 if (applicationName is not null) { hostingEnvironment.ApplicationName = applicationName; } // 根据 ContentRootPath 创建一个 PhysicalFileProvider,并将其设置为 HostingEnvironment 的 ContentRootFileProvider。 var physicalFileProvider = new PhysicalFileProvider(hostingEnvironment.ContentRootPath); hostingEnvironment.ContentRootFileProvider = physicalFileProvider; // 返回创建的 HostingEnvironment 对象和关联的 PhysicalFileProvider 对象。 return (hostingEnvironment, physicalFileProvider); }
主要属性:
-
EnvironmentName:
- 类型:
string
- 功能: 表示当前应用程序的运行环境名称,如“Development”、“Staging”或“Production”。该值通常由环境变量来
ASPNETCORE_ENVIRONMENT
设置。 - 用途:可以根据环境名称切换配置,例如在开发环境下启用调试功能,而在生产环境下禁用调试。
- 类型:
-
ApplcationName:
- 类型:
string
- 功能:表示应用程序的名称,通常是包含应用程序入口点的程序集名称。
- 用途:可以用于日志记录、配置文件命名等需要使用应用程序名称的场景。
- 类型:
-
WebRootPath:
- 类型:
string
- 功能:表示Web应用程序的根目录路径,通常包含静态文件,如HTML、CSS、JavaScript等。
- 用途:允许开发者访问和管理Web根目录下的内容。
- 类型:
-
WebRootFileProvider:
- 型:
IFileProvider
- 功能:提供对
WebRootPath
目录下文件的访问。 - 用途: 通过
IFileProvider
可以读取、监视或访问 Web 根目录中的文件。
- 型:
-
ContentRootPath:
- 类型:
string
- 功能:通常表示应用程序内容的根目录路径,是应用程序的基目录,包含配置文件、视图文件、数据文件等。
- 用途:用于定位和访问应用程序的内容文件。
- 类型:
-
ContentRootFileProvider:
- 类型:
IFileProvider
- 功能:提供对
ContentRootPath
目录下文件的访问。 - 用途: 通过
IFileProvider
可以读取、监视或访问应用程序内容目录中的文件。
- 类型:
有时候不是我们失去了目标,而是失去了方向。