HostingEnvironment是承载应用当前执行环境的描述,它是对所有实现了IHostingEnvironment接口的所有类型以及对应对象的统称。如下面的代码片段所示,一个HostingEnvironment对象承载的执行环境的描述信息体现在定义这个接口的6个属性上。ApplicationName和EnvironmentName分别代表当前应用的名称和执行环境的名称。WebRootPath和ContentRootPath是指向两个根目录的路径,前者指向的目录用于存放可供外界通过HTTP请求访问的资源,后者指向的目录存放的则是应用自身内部所需的资源。至于这个接口的ContentRootFileProvider和WebRootFileProvider属性返回的则是针对这两个目录的FileProvider对象。如下所示的HostingEnvironment类型是对IHostingEnvironment接口的默认实现。[本文已经同步到《ASP.NET Core框架揭秘》之中]

   1: public interface IHostingEnvironment

   2: {

   3:     string         ApplicationName { get; set; }

   4:     string         EnvironmentName { get; set; }

   5:     IFileProvider  ContentRootFileProvider { get; set; }

   6:     string         ContentRootPath { get; set; }

   7:     IFileProvider  WebRootFileProvider { get; set; }

   8:     string         WebRootPath { get; set; }

   9: }

  10:  

  11: public class HostingEnvironment : IHostingEnvironment

  12: {

  13:     string         ApplicationName { get; set; }

  14:     string         EnvironmentName { get; set; }

  15:     IFileProvider  ContentRootFileProvider { get; set; }

  16:     string         ContentRootPath { get; set; }

  17:     IFileProvider  WebRootFileProvider { get; set; }

  18:     string         WebRootPath { get; set; }

  19: }

一、ApplicationEnvironment

接下来我们会对HostingEnvironment对象承载的执行环境描述信息的来源进行详细介绍,不过在此之前我们有必要来了解另一个名为ApplicationEnvironment的类型,它定义在 “Microsoft.Extensions.PlatformAbstractions”这个NuGet包中。我们从其命名也可以看出这个对象描述的也是与执行环境相关的信息,而它承载的这些信息提下在如下四个属性成员上,它们分别表示应用的名称、基路径、版本和采用的.NET Framework。

   1: public class ApplicationEnvironment

   2: {

   3:     public string         ApplicationName {  get; }

   4:     public string         ApplicationBasePath {  get; }

   5:     public string         ApplicationVersion {  get; }

   6:     public FrameworkName  RuntimeFramework { get; }

   7: }

如果需要获取一个ApplicationEnvironment对象来描述当前执行环境,我们需要使用到如下这个名为PlatformServices的对象,它的Application属性返回的就是我们所需的ApplicationEnvironment对象。因为该类型并不存在一个公共的构函数,所以我们不能直接实例化一个PlatformServices对象,不过我们可以利用Default属性得到这个单例对象。

   1: public class PlatformServices

   2: {

   3:     private PlatformServices();

   4:     public ApplicationEnvironment     Application { get; }

   5:     public static PlatformServices    Default { get; }

   6: }

对于一个ApplicationEnvironment对象来说,它的ApplicationName、ApplicationVersion和RuntimeFramework属性决定于定义了程序入口Main方法的程序集,具体来说ApplicationName和ApplicationVersion分别返回这个程序集名称和版本,而这个编译这个程序集采用的.NET Framework的版本对应的正是RuntimeFramework属性。至于ApplicationBasePath属性,它返回的实际上是AppContext的BaseDirectoryPath属性对应的路径,运行时使用这个基础路径来解析被加载的目标程序集的真实路径。针对这四个属性的取值可以通过下面这段程序来验证。

   1: public class Program

   2: {

   3:     public static void Main()

   4:     {

   5:         Assembly assembly = typeof(Program).GetTypeInfo().Assembly;

   6:         AssemblyName assemblyName = assembly.GetName();

   7:         ApplicationEnvironment env = PlatformServices.Default.Application;

   8:  

   9:         Debug.Assert(env.ApplicationBasePath == AppContext.BaseDirectory);

  10:         Debug.Assert(env.ApplicationName == assemblyName.Name);

  11:         Debug.Assert(env.ApplicationVersion == assemblyName.Version.ToString());

  12:         Debug.Assert(env.RuntimeFramework.ToString() == assembly.GetCustomAttribute<TargetFrameworkAttribute>().FrameworkName);

  13:     }

  14: }

如果我们没有对应用的名称做显式设置,当前HostingEnvironment的ApplicationName属性体现的应用名称来源于这个ApplicationEnvironment对象的同名属性。HostingEnvironment包括ApplicationName在内的四个属性(不包括WebRootFileProvider和ContentRootFileProvider属性,因为它们决定于对应ContentRootPath和WebRootPath属性)都可以通过WebHostOptions来设置。通过前面一章的介绍我们知道WebHostOptions对象是根据WebHostBuilder的采用的配置来创建的,所以我们可以利用配置的方式来决定执行环境。

二、Configuration和WebHostOptions

对于通过HostingEnvironment的四个属性(ApplicationName、EnvironmentName、WebRootPath和ContentRootPath) 承载的四个与执行环境相关的设置,在WebHostOptions对象上都具有对应的属性,后者是前者的数据来源。由于WebHostOptions对象是WebHostBuilder根据它采用的配置来创建的,所以这些设置最初来源于使用的配置。值得一提的是,如果EnvironmentName属性未作显式设置,它使用的默认值为“Production”。

由于WebHostBuilder会采用环境变量作为配置来源,并且采用“ASPNETCORE_”作为环境变量过滤采用的前缀,所以我们完全可以按照如下的方式通过设置环境变量的方式来初始化由HostingEnvironment承载的执行环境选项。

   1: Environment.SetEnvironmentVariable("ASPNETCORE_APPLICATIONNAME", "MyApp");

   2: Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Staging");

   3: Environment.SetEnvironmentVariable("ASPNETCORE_WEBROOT", @"c:\myapp\wwwroot\");

   4: Environment.SetEnvironmentVariable("ASPNETCORE_CONTENTROOT", @"c:\myapp\contentroot");

   5:  

   6: new WebHostBuilder()

   7:     .UseConfiguration(new ConfigurationBuilder().AddJsonFile("weboptions.json"))

   8:     .ConfigureServices(svcs => {

   9:         IHostingEnvironment env = svcs.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();

  10:         Debug.Assert(env.ApplicationName == "MyApp");

  11:         Debug.Assert(env.EnvironmentName == "Staging");

  12:         Debug.Assert(env.WebRootPath == @"c:\myapp\wwwroot\");

  13:         Debug.Assert(env.ContentRootPath == @"c:\myapp\contentroot");

  14:     })

  15:     .UseKestrel()

  16:     .Build();

虽然WebHostBuilder默认使用环境变量作为配置源,但是我们可以显式地创建一个Configuration对象并通过调用它的扩展方法UseConfiguration进行“导入”。对于上面这段程序,如果我们将配置定义在一个具有如下结构的JSON文件(weboptions.json),我们只需要在创建WebHost之前按照如下的方式调用UseConfiguration方法将对应配置导入进来即可。

weboptions.json:

   1: {

   2:   "applicationName": "MyApp",

   3:   "environment"    : "Staging",

   4:   "webRoot"        : "c:\\myapp\\wwwroot",

   5:   "contentRoot"    : "c:\\myapp\\contentroot"

   6: }

Program

   1: new WebHostBuilder()

   2:     .UseConfiguration(new ConfigurationBuilder().AddJsonFile("weboptions.json").Build())

   3:     .ConfigureServices(svcs => {

   4:         IHostingEnvironment env = svcs.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();

   5:         Debug.Assert(env.ApplicationName  == "MyApp");

   6:         Debug.Assert(env.EnvironmentName  == "Staging");

   7:         Debug.Assert(env.WebRootPath       == @"c:\myapp\wwwroot\");

   8:         Debug.Assert(env.ContentRootPath  == @"c:\myapp\contentroot");

   9:     })

  10:     .UseKestrel()

  11:     .Build();

三、特殊的ApplicationName

对于HostingEnvironment的这四个属性来说,表示应用名称的ApplicationName比较特殊。虽然它的初始值来源于配置,当我们调用Configure方法或者UseStartup方法是,这个属性会被覆盖。如下这段程序与上面不同之处在于创建WebHost之前调用Configure方法,我们采用环境变量设置的应用名(“MyApp”)将失效。

   1: Environment.SetEnvironmentVariable("ASPNETCORE_APPLICATIONNAME", "MyApp");

   2: new WebHostBuilder()

   3:     .ConfigureServices(svcs => {

   4:         IHostingEnvironment env = svcs.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();

   5:         Debug.Assert(env.ApplicationName != "MyApp");

   6:     })

   7:     .UseKestrel()

   8:     .Configure(app => {})

   9: .Build();

其实这个问题的答案我们在《应用的入口——Startup》中已经给出了。如下所示的是WebHostBuilder用于注册Startup的两个扩展方法Configure和UseStartup的定义,我们可以清楚地看到在创建并注册Startup之前,它们都会设置当前应用的名称。

   1: public static class WebHostBuilderExtensions

   2: {    

   3:     public static IWebHostBuilder Configure(this IWebHostBuilder hostBuilder, Action<IApplicationBuilder> configureApp)

   4:     {

   5:         var startupAssemblyName = configureApp.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name;

   6:  

   7:         return hostBuilder

   8:             .UseSetting("applicationName", startupAssemblyName)

   9:             …

  10:     }

  11:  

  12:     public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType)

  13:     {

  14:         var startupAssemblyName = startupType.GetTypeInfo().Assembly.GetName().Name;

  15:         return hostBuilder

  16:             .UseSetting("ApplicationName", startupAssemblyName)

  17:             ...           

  18:     }

  19: }

如果我们调用WebHostBuilder的UseStartup方法设置了一个启动类,那么这个类型所在的程序集名称将作为当前应用的名称。如果我们通过Configure方法并提供了一个Action<IApplicationBuilder>类型的委托对象,那么这个委托对象对应方法被定义在哪个类型中,这个类型所在的程序基名称将会作为应用名称。对于后一种情况,我们可以采用如下两种方式来提供这个Action<IApplicationBuilder>对象,最终将会导致设置的应用名称完全不同。

   1: public static class Startup

   2: {

   3:     public static void Configure(IApplicationBuilder app);

   4: }

   5:  

   6: //Configure(app=>Startup.Configure(app))

   7: new WebHostBuilder()

   8:     .ConfigureServices(svcs => {

   9:         IHostingEnvironment env = svcs.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();

  10:         Debug.Assert(env.ApplicationName == Assembly.GetEntryAssembly().GetName().Name);

  11:     })

  12:     .UseKestrel()

  13:     .Configure(app=>Startup.Configure(app))

  14:     .Build();

  15:  

  16: //Configure(Startup.Configure)

  17: new WebHostBuilder()

  18:     .ConfigureServices(svcs => {

  19:         IHostingEnvironment env = svcs.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();

  20:         Debug.Assert(env.ApplicationName == typeof(Startup).GetTypeInfo().Assembly.GetName().Name);

  21:     })

  22:     .UseKestrel()

  23:     .Configure(Startup.Configure)

  24:     .Build();

在ASP.NET Core应用中如何设置和获取与执行环境相关的信息?的更多相关文章

  1. ASP.NET MVC和ASP.NET Core MVC中获取当前URL/Controller/Action (转载)

    ASP.NET MVC 一.获取URL(ASP.NET通用): [1]获取完整url(协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [ ...

  2. ASP.NET Core MVC 中设置全局异常处理方式

    在asp.net core mvc中,如果有未处理的异常发生后,会返回http500错误,对于最终用户来说,显然不是特别友好.那如何对于这些未处理的异常显示统一的错误提示页面呢? 在asp.net c ...

  3. 通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[下]:管道是如何构建起来的?

    在<中篇>中,我们对管道的构成以及它对请求的处理流程进行了详细介绍,接下来我们需要了解的是这样一个管道是如何被构建起来的.总的来说,管道由一个服务器和一个HttpApplication构成 ...

  4. ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存

    .NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...

  5. 006.Adding a controller to a ASP.NET Core MVC app with Visual Studio -- 【在asp.net core mvc 中添加一个控制器】

    Adding a controller to a ASP.NET Core MVC app with Visual Studio 在asp.net core mvc 中添加一个控制器 2017-2-2 ...

  6. 在 ASP.NET Core 项目中实现小写的路由URL

    在 ASP.NET MVC 早期版本中,我们可以通过在应用的 RegisterRoutes 方法中设置 routes.LowercaseUrls = true ; 来将页面的 URL 链接转小写.在 ...

  7. 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】

    Adding a view to an ASP.NET Core MVC app 在asp.net core mvc中添加视图 2017-3-4 7 分钟阅读时长 本文内容 1.Changing vi ...

  8. 如何在 ASP.NET Core 测试中操纵时间?

    有时候,我们会遇到一些跟系统当前时间相关的需求,例如: 只有开学季才允许录入学生信息 只有到了晚上或者周六才允许备份博客 注册满 3 天的用户才允许进行一些操作 某用户在 24 小时内被禁止发言 很显 ...

  9. ASP.NET Core MVC中URL和数据模型的匹配

    Http GET方法 首先我们来看看GET方法的Http请求,URL参数和ASP.NET Core MVC中Controller的Action方法参数匹配情况. 我定义一个UserController ...

随机推荐

  1. 虾扯蛋:Android View动画 Animation不完全解析

    本文结合一些周知的概念和源码片段,对View动画的工作原理进行挖掘和分析.以下不是对源码一丝不苟的分析过程,只是以搞清楚Animation的执行过程.如何被周期性调用为目标粗略分析下相关方法的执行细节 ...

  2. 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM

    刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...

  3. ABP文档 - Mvc 控制器

    文档目录 本节内容: 简介 AbpController基类 本地化 其它 过滤 异常处理和结果包装 审计日志 验证 授权 工作单元 反伪造 模型绑定器 简介 ABP通过nuget包Abp.Web.Mv ...

  4. Hawk 4.6 并行化

    并行化 Hawk支持单机并行化,也就是使用多线程获取数据.它可以控制目前所有任务的数量,为了不给网站造成过大的压力,仅当任务池中的任务数量小于一定值后,才会插入新的任务. 你可以在数据清洗的 执行面板 ...

  5. HTML5轻松实现搜索框提示文字点击消失---及placeholder颜色的设置

    在做搜索框的时候无意间发现html5的input里有个placeholder属性能轻松实现提示文字点击消失功能,之前还傻傻的在用js来实现类似功能... 示例 <form action=&quo ...

  6. js callee,caller学习

    原文地址:js callee,caller学习 /* * caller 返回一个对函数的引用,该函数调用了当前函数. * 如果函数是由顶层调用的,那么 caller包含的就是 null . * 如果在 ...

  7. JAVA FreeMarker工具类

    FreeMarkerUtil.java package pers.kangxu.datautils.utils; import java.io.File; import java.io.StringW ...

  8. 【干货分享】流程DEMO-加班与调休

    流程名: 加班.调休  业务描述: 加班: 工作日加班可以申请调休,也可以申请支付加班费.原则上都应申请调休:周末加班原则上申请调休:法定节假日加班支付加班费. 加班申请以半小时为单位. 当月加班不能 ...

  9. iOS app内存分析套路

    iOS app内存分析套路 Xcode下查看app内存使用情况有2中方法: Navigator导航栏中的Debug navigator中的Memory Instruments 一.Debug navi ...

  10. 2-1 Linux 操作系统及常用命令

    根据马哥linux初级视频 2-1.2-2来编辑 1. GUI与CLI GUI: Graphic User Interface CLI: Command Line Interface 注:在Windo ...