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 = 20000000;
});设置主机时,可以提供配置和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", "8080")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主机的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。
 
             我要评论
我要评论 
                                             
                                             
                                             
                                            
发表评论