1.前言

ASP.NET Core应用程序可以配置和启动主机(Host)。主机负责应用程序启动和生命周期管理,配置服务器和请求处理管道。主机还可以设置日志记录、依赖关系注入和配置。而Host主机又包括Web主机(IWebHostBuilder)和通用主机(IHostBuilder)。该章节主要介绍了用于托管Web应用的Web主机。对于其他类型的应用,请使用通用主机。

2.设置主机

创建使用IWebHostBuilder实例的主机。通常在应用程序的入口点来执行Main方法。在项目模板中,Main位于Program.cs。典型应用默认调用CreateDefaultBuilder来开始创建主机:

public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}

2.1执行下列任务

调用CreateDefaultBuilder的代码位于名为CreateWebHostBuilder的方法中,这让它区分于 Main中对生成器对象调用Run的代码。CreateDefaultBuilder执行下列任务:
●使用应用程序的托管配置提供应用程序将Kestrel服务器配置为Web服务器。
●将内容根设置为由 Directory.GetCurrentDirectory返回的路径。
●通过以下对象加载主机配置:
  ○前缀为ASPNETCORE_的环境变量(例如,ASPNETCORE_ENVIRONMENT)。
  ○命令行参数。
●按以下顺序加载应用程序配置:
  ○appsettings.json。
  ○appsettings.{Environment}.json。
  ○应用在使用入口程序集的Development环境中运行时的机密管理器。
  ○环境变量。
  ○命令行参数。
●配置控制台和调试输出的日志记录。日志记录包含appsettings.json或appsettings.{Environment}.json文件的日志记录配置部分中指定的日志筛选规则。
●使用ASP.NET Core模块在IIS后面运行时,CreateDefaultBuilder会启用IIS集成,这会配置应用程序的基址和端口。IIS集成还配置应用程序以捕获启动错误。
●如果应用环境为“开发(Development)”,请将ServiceProviderOptions.ValidateScopes设为true。

2.2重写和增强定义的配置

ConfigureAppConfiguration、ConfigureLogging以及IWebHostBuilder的其他方法和扩展方法可重写和增强CreateDefaultBuilder定义的配置。下面是一些示例:
ConfigureAppConfiguration:用于指定应用程序的其他IConfiguration。下面的ConfigureAppConfiguration调用添加委托,以在appsettings.xml文件中添加应用程序配置,该示例在Core系列第11章节有演示。可多次调用ConfigureAppConfiguration。请注意,此配置不适用于主机(例如,服务器URL或环境)。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
});

ConfigureLogging:ConfigureLogging调用添加委托,将最小日志记录级别 (SetMinimumLevel)配置为LogLevel.Warning。此设置重写CreateDefaultBuilder在appsettings.Development.json和appsettings.Production.json中配置,分别为LogLevel.Debug和LogLevel.Error。可多次调用 ConfigureLogging。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Warning);
});

ConfigureKestrel:调用ConfigureKestrel来重写CreateDefaultBuilder在配置Kestrel时建立的30,000,000字节默认Limits.MaxRequestBodySize:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureKestrel((context, options) =>
{
options.Limits.MaxRequestBodySize = ;
});

设置主机时,可以提供配置和ConfigureServices方法。如果指定Startup类,必须定义Configure方法。

3.主机配置值

WebHostBuilder依赖于以下的方法设置主机配置值:
●主机生成器配置,其中包括格式ASPNETCORE_{configurationKey}的环境变量。例如 ASPNETCORE_ENVIRONMENT。
●UseContentRoot和UseConfiguration等扩展。
●UseSetting和关联键。使用UseSetting设置值时,该值设置为无论何种类型的字符串。

3.1应用程序键(名称)

在主机构造期间调用UseStartup或Configure时,会自动设置 IHostingEnvironment.ApplicationName属性。该值设置为包含应用入口点的程序集的名称。要显式设置值,请使用WebHostDefaults.ApplicationKey(环境变量:ASPNETCORE_APPLICATIONNAME):

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//应用程序默认名称为:CoreWeb (也就是项目名称)
  string an = env.ApplicationName;
  ...
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args).UseStartup<Startup>()
.UseSetting(WebHostDefaults.ApplicationKey, "CoreWeb");

3.2捕获启动错误

此设置控制启动错误的捕获。当false时,启动期间出错导致主机退出。当true时,主机在启动期间捕获异常并尝试启动服务器(环境变量:ASPNETCORE_CAPTURESTARTUPERRORS)。

WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)

3.3内容根

此设置确定ASP.NET Core开始搜索内容文件,如MVC视图等。内容根也用作Web根设置的基路径。如果路径不存在,主机将无法启动(环境变量:ASPNETCORE_CONTENTROOT)。

WebHost.CreateDefaultBuilder(args)
.UseContentRoot("c:\\<content-root>")

3.4详细错误

确定是否应捕获详细错误。启用(或当环境设置为Development)时,应用捕获详细的异常(环境变量:ASPNETCORE_DETAILEDERRORS)。

WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.DetailedErrorsKey, "true")

3.5环境

设置应用程序的环境。环境可以设置为任何值。框架定义的值包括Development、Staging和Production。值不区分大小写。默认情况下,从ASPNETCORE_ENVIRONMENT环境变量读取环境。使用Visual Studio时,可能会在launchSettings.json文件中设置环境变量。有关于环境详情信息,可以移步到Core系列第10章节有参阅(环境变量:ASPNETCORE_ENVIRONMENT)。

WebHost.CreateDefaultBuilder(args)
.UseEnvironment(EnvironmentName.Development)

3.6HTTPS端口

设置HTTPS重定向端口。用于强制实施HTTPS(环境变量:ASPNETCORE_HTTPS_PORT)。

WebHost.CreateDefaultBuilder(args)
.UseSetting("https_port", "")

3.7服务器(Kestrel) URL

指示IP地址或主机地址,其中包含服务器应针对请求侦听的端口和协议。设置为服务器应响应的以分号分隔 (;) 的URL前缀列表。例如 http://localhost:123。使用“*”指示服务器应针对请求侦听的使用特定端口和协议(例如 http://*:5000)的IP地址或主机名。协议(http://或https://)必须包含每个URL。不同的服务器支持的格式有所不同(环境变量:ASPNETCORE_URLS)。

WebHost.CreateDefaultBuilder(args)
.UseUrls("https://*:5000;https://localhost:5001;https://hostname:5002")

4.重写配置

使用配置可以配置Web主机。在下面的示例中,主机配置是根据需要在hostsettings.json文件中指定。命令行参数可能会重写从hostsettings.json文件加载的任何配置。生成的配置(在config中)用于通过UseConfiguration配置主机。
新建一个hostsettings.json文件,内容如下:

{
"urls": "https://*:5005"
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
//IConfigurationBuilder的配置主机
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
//主机配置在hostsettings.json文件中指定
.AddJsonFile("hostsettings.json", optional: true)
//输入的命令行参数可能会重写从hostsettings.json文件加载的任何配置
.AddCommandLine(args)
.Build(); return WebHost.CreateDefaultBuilder(args)
.UseUrls("https://*:5001")
.UseConfiguration(config)
.Configure(app =>
{
//生成的配置委托函数
app.Run(context =>
context.Response.WriteAsync("Hello, World!"));
});
}

上述代码描述意思是若要指定在特定的URL上运行的主机,所需的值可以在执行dotnet运行时从命令提示符传入。命令行参数重写hostsettings.json文件中的urls值,且服务器侦听端口8080:

dotnet run --urls "http://*:8080"

主机启动时,先用hostsettings.json config重写UseUrls提供的urls参数配置,然后再用命令行参数config重写hostsettings.json config的urls参数配置。

5.管理主机

管理主机启动方式有Run和Start两种。Run方法启动Web应用程序并阻止调用线程,直到关闭主机。Start方法通过调用自身以非阻止方式运行主机。

//Run
CreateWebHostBuilder(args).Build().Run();
//Start:非阻止方式,所有必须加上ReadLine
CreateWebHostBuilder(args).Build().Start();
Console.ReadLine();

6.IHostingEnvironment接口

IHostingEnvironment接口提供有关应用的Web承载环境的信息。使用构造函数注入获取 IHostingEnvironment以使用其属性和扩展方法:

//示例1:
public class CustomFileReader
{
private readonly IHostingEnvironment _env; public CustomFileReader(IHostingEnvironment env)
{
_env = env;
}
public string ReadFile(string filePath)
{
var fileProvider = _env.WebRootFileProvider;
// Process the file here
}
}

可以用于在启动时基于环境配置应用程序或者将IHostingEnvironment注入到Startup构造函数,用于ConfigureServices:

//示例2:
public class Startup
{
public Startup(IHostingEnvironment env)
{
HostingEnvironment = env;
}
public IHostingEnvironment HostingEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
if (HostingEnvironment.IsDevelopment())
{
// Development configuration
}
else
{
// Staging/Production configuration
}
var contentRootPath = HostingEnvironment.ContentRootPath;
}
}

IHostingEnvironment服务还可以直接注入到Configure方法以设置处理管道:

//示例3:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
// In Development, use the Developer Exception Page
app.UseDeveloperExceptionPage();
}
else
{
// In Staging/Production, route exceptions to /error
app.UseExceptionHandler("/error");
}
var contentRootPath = env.ContentRootPath;
}

创建自定义中间件(要了解中间件的同学们,可以移步到第四章节学习)时可以将IHostingEnvironment 注入Invoke方法:

public async Task Invoke(HttpContext context, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
// Configure middleware for Development
}
else
{
// Configure middleware for Staging/Production
}
var contentRootPath = env.ContentRootPath;
}

7.IApplicationLifetime接口

IApplicationLifetime允许后启动和关闭活动。接口上的三个属性是用于注册Action方法(用于定义启动和关闭事件)的取消标记。

取消标记

触发条件

ApplicationStarted

主机已完全启动。

ApplicationStopped

主机正在完成正常关闭。应处理所有请求。 关闭受到阻止,直到完成此事件。

ApplicationStopping

主机正在执行正常关闭。仍在处理请求。关闭受到阻止,直到完成此事件。

public class Startup
{
public void Configure(IApplicationBuilder app, IApplicationLifetime appLifetime)
{
appLifetime.ApplicationStarted.Register(OnStarted);
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
Console.CancelKeyPress += (sender, eventArgs) =>
{
appLifetime.StopApplication();
// Don't terminate the process immediately, wait for the Main thread to exit gracefully.
eventArgs.Cancel = true;
};
}
private void OnStarted()
{
// Perform post-startup activities here
}
private void OnStopping()
{
// Perform on-stopping activities here
}
private void OnStopped()
{
// Perform post-stopped activities here
}
}

StopApplication是请求应用终止的意思。以下类在调用类的Shutdown方法时使用StopApplication正常关闭应用:

public class MyClass
{
private readonly IApplicationLifetime _appLifetime;
public MyClass(IApplicationLifetime appLifetime)
{
_appLifetime = appLifetime;
}
public void Shutdown()
{
_appLifetime.StopApplication();
}
}

8.作用域验证

如果应用环境为“开发(Development)”,则CreateDefaultBuilder将ServiceProviderOptions.ValidateScopes设为true。若将ValidateScopes设为true,默认服务提供应用程序会执行检查来验证以下内容:
●作用域服务不能直接或间接地从根服务提供者解析。
●作用域服务不会直接或间接地注入到单例中(服务的生命周期)。
若要始终验证作用域(包括在生命周期环境中验证),请使用主机生成器上的 UseDefaultServiceProvider配置ServiceProviderOptions:

WebHost.CreateDefaultBuilder(args)
.UseDefaultServiceProvider((context, options) => {
options.ValidateScopes = true;
})

参考文献:
ASP.NET Core Web主机

(15)ASP.NET Core Web主机(IWebHostBuilder)的更多相关文章

  1. asp.net core 系列 16 Web主机 IWebHostBuilder

    一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...

  2. ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试

    想必大家之前在进行ASP.NET Web 应用程序开发期间都有用到过将我们的网站部署到IIS自定义主机域名并附加到进程进行调试. 那我们的ASP.NET Core Web 应用程序又是如何部署到我们的 ...

  3. docker中运行ASP.NET Core Web API

    在docker中运行ASP.NET Core Web API应用程序 本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过 ...

  4. 使用JWT创建安全的ASP.NET Core Web API

    在本文中,你将学习如何在ASP.NET Core Web API中使用JWT身份验证.我将在编写代码时逐步简化.我们将构建两个终结点,一个用于客户登录,另一个用于获取客户订单.这些api将连接到在本地 ...

  5. Docker容器环境下ASP.NET Core Web API应用程序的调试

    本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...

  6. 在docker中运行ASP.NET Core Web API应用程序

    本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过程中,也会对docker的使用进行一些简单的描述.对于.NET Cor ...

  7. Docker容器环境下ASP.NET Core Web API

    Docker容器环境下ASP.NET Core Web API应用程序的调试 本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Dock ...

  8. ASP.NET Core Web API下事件驱动型架构的实现(一):一个简单的实现

    很长一段时间以来,我都在思考如何在ASP.NET Core的框架下,实现一套完整的事件驱动型架构.这个问题看上去有点大,其实主要目标是为了实现一个基于ASP.NET Core的微服务,它能够非常简单地 ...

  9. ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入支付宝-电脑网页支付接口及同步跳转及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET ...

随机推荐

  1. python数据库-数据库的介绍及安装(47)

    一.数据库的介绍 数据库(Database)是存储与管理数据的软件系统,就像一个存入数据的物流仓库.每个数据库都有一个或多个不同的API接口用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数 ...

  2. java-IO各个区别

    BIO:JDK1.4以前用的都是BIO,阻塞IO. 阻塞到我们的读写方法.BIO,如果有一台服务器,能承受简单的客户端请求,那么使用io和net中的同步.阻塞式API应该是可以实现了.但是为了一个用户 ...

  3. HDU 2896:病毒侵袭(AC自动机)

    http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:中文题意. 思路:AC自动机模板题.主要在于字符有128种,输出还要排序和去重! 注意是“total ...

  4. 深入学习Spring框架(一)- 入门

    1.Spring是什么? Spring是一个JavaEE轻量级的一站式开发框架. JavaEE: 就是用于开发B/S的程序.(企业级) 轻量级:使用最少代码启动框架,然后根据你的需求选择,选择你喜欢的 ...

  5. 从零开始实现放置游戏(十)——实现战斗挂机(1)hessian服务端搭建

    前面实现RMS系统时,我们让其直接访问底层数据库.后面我们在idlewow-game模块实现游戏逻辑时,将不再直接访问底层数据,而是通过hessian服务暴露接口给表现层. 本章,我们先把hessia ...

  6. Java学习笔记之---集合

    Java学习笔记之---集合 (一)集合框架的体系结构 (二)List(列表) (1)特性 1.List中的元素是有序并且可以重复的,成为序列 2.List可以精确的控制每个元素的插入位置,并且可以删 ...

  7. NDK_OVERVIEW翻译

    Android NDK Overview Introduction: The Android NDK is a set of tools that allows Android application ...

  8. 缓存实践Cache Aside Pattern

    Cache Aside Pattern旁路缓存,是对缓存应用的一个总结,包括读数据方案和写数据方案. 读数据方案 先读cache,如果命中则返回 如果miss则读db 将db的数据存入缓存 写数据方案 ...

  9. JAVA面试题 StringBuffer和StringBuilder的区别,从源码角度分析?

    面试官Q1:请问StringBuffer和StringBuilder有什么区别? 这是一个老生常谈的话题,笔者前几年每次面试都会被问到,作为基础面试题,被问到的概率百分之八九十.下面我们从面试需要答到 ...

  10. C#2.0新增功能01 分布类与分部方法

    连载目录    [已更新最新开发文章,点击查看详细] 分部类型 拆分一个类.一个结构.一个接口或一个方法的定义到两个或更多的文件中, 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组 ...