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. MIP开发常见问题解答

    校验相关 1. MIP 页面的 <a>链接校验报错,MIP 是强制 target="_blank" 吗? 如果想直接跳转MIP页,可以用mip-link 组件:MIP ...

  2. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  3. 阿里签名中URLEncode于C#URLEncod不同之处

    问题 如上图所示,阿里云的PercentEncode 转换! 为 %21 PercentEncode 源码为: package com.aliyuncs.auth; import java.io.Un ...

  4. RxJS + Redux + React = Amazing!(译二)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...

  5. [转]利用URLConnection来发送POST和GET请求

    URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...

  6. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  7. Zabbix基本配置及监控主机

    监控主机一版需要在被监控的主机上安装Zabbix Agent 监控主机 安装zabbix-agent 首先需要在被监控的主机上安装agent,可以下载预编译好的RPM进行安装,下载地址:http:// ...

  8. 【C#附源码】数据库文档生成工具支持(Excel+Html)

    [2015] 很多时候,我们在生成数据库文档时,使用某些工具,可效果总不理想,不是内容不详细,就是表现效果一般般.很多还是word.html的.看着真是别扭.本人习惯用Excel,所以闲暇时,就简单的 ...

  9. 【知识必备】一文让你搞懂design设计的CoordinatorLayout和AppbarLayout联动,让Design设计更简单~

    一.写在前面 其实博主在之前已经对design包的各个控件都做了博文说明,无奈个人觉得理解不够深入,所以有了这篇更加深入的介绍,希望各位看官拍砖~ 二.从是什么开始 1.首先我们得知道Coordina ...

  10. java设计模式之--单例模式

    前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...