ASP.NET Core 應(yīng)用配置和啟動(dòng)“主機(jī)”。 主機(jī)負(fù)責(zé)應(yīng)用程序啟動(dòng)和生存期管理。 至少,主機(jī)配置服務(wù)器和請(qǐng)求處理管道。 主機(jī)還可以設(shè)置日志記錄、依賴關(guān)系注入和配置。
本文介紹了 ASP.NET Core Web 主機(jī) (IWebHostBuilder),該主機(jī)用于托管 Web 應(yīng)用。 有關(guān) .NET 泛型主機(jī) (IHostBuilder) 的信息,請(qǐng)參閱 .NET 通用主機(jī)。
創(chuàng)建使用 IWebHostBuilder 實(shí)例的主機(jī)。 通常在應(yīng)用的入口點(diǎn)來(lái)執(zhí)行 Main 方法。 在項(xiàng)目模板中,Main 位于 Program.cs。 典型的 Program.cs 調(diào)用 CreateDefaultBuilder 以開(kāi)始設(shè)置主機(jī):
C#
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
CreateDefaultBuilder 執(zhí)行下列任務(wù):
ConfigureAppConfiguration、ConfigureLogging 以及 IWebHostBuilder 的其他方法和擴(kuò)展方法可重寫和增強(qiáng) CreateDefaultBuilder 定義的配置。 下面是一些示例:
內(nèi)容根確定主機(jī)搜索內(nèi)容文件(如 MVC 視圖文件)的位置。 應(yīng)用從項(xiàng)目的根文件夾啟動(dòng)時(shí),會(huì)將項(xiàng)目的根文件夾用作內(nèi)容根。 這是 Visual Studio 和 dotnet new 模板中使用的默認(rèn)值。
有關(guān)應(yīng)用配置的詳細(xì)信息,請(qǐng)參閱 ASP.NET Core 中的配置。
備注
作為使用靜態(tài) CreateDefaultBuilder 方法的替代方法,從 WebHostBuilder 創(chuàng)建主機(jī)是一種受 ASP.NET Core 2.x 支持的方法。 有關(guān)詳細(xì)信息,請(qǐng)參閱 ASP.NET Core 1.x 選項(xiàng)卡。
設(shè)置主機(jī)時(shí),可以提供配置和 ConfigureServices 方法。 如果指定 Startup 類,必須定義 Configure 方法。 有關(guān)更多信息,請(qǐng)參見(jiàn)ASP.NET Core 中的應(yīng)用啟動(dòng)。 多次調(diào)用 ConfigureServices 將追加到另一個(gè)。 多次調(diào)用 WebHostBuilder 上的 Configure 或 UseStartup 將替換以前的設(shè)置。
WebHostBuilder 依賴于以下的方法設(shè)置主機(jī)配置值:
主機(jī)使用任何一個(gè)選項(xiàng)設(shè)置上一個(gè)值。 有關(guān)詳細(xì)信息,請(qǐng)參閱下一部分中的重寫配置。
在主機(jī)構(gòu)造期間調(diào)用 UseStartup 或 Configure 時(shí),會(huì)自動(dòng)設(shè)置 IHostingEnvironment.ApplicationName 屬性。 該值設(shè)置為包含應(yīng)用入口點(diǎn)的程序集的名稱。 要顯式設(shè)置值,請(qǐng)使用 WebHostDefaults.ApplicationKey:
密鑰:applicationName類型:string默認(rèn)值:包含應(yīng)用入口點(diǎn)的程序集的名稱。設(shè)置使用:UseSetting環(huán)境變量:ASPNETCORE_APPLICATIONNAME
C#
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")
此設(shè)置控制啟動(dòng)錯(cuò)誤的捕獲。
鍵:captureStartupErrors類型:布爾型(true 或 1)默認(rèn)值:默認(rèn)為 false,除非應(yīng)用使用 Kestrel 在 IIS 后方運(yùn)行,其中默認(rèn)值是 true。設(shè)置使用:CaptureStartupErrors環(huán)境變量:ASPNETCORE_CAPTURESTARTUPERRORS
當(dāng) false 時(shí),啟動(dòng)期間出錯(cuò)導(dǎo)致主機(jī)退出。 當(dāng) true 時(shí),主機(jī)在啟動(dòng)期間捕獲異常并嘗試啟動(dòng)服務(wù)器。
C#
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
此設(shè)置確定 ASP.NET Core 開(kāi)始搜索內(nèi)容文件,如 MVC 視圖等。
鍵:contentRoot類型:string默認(rèn)值:默認(rèn)為應(yīng)用程序集所在的文件夾。設(shè)置使用:UseContentRoot環(huán)境變量:ASPNETCORE_CONTENTROOT
內(nèi)容根也用作 Web 根設(shè)置的基路徑。 如果路徑不存在,主機(jī)將無(wú)法啟動(dòng)。
C#
WebHost.CreateDefaultBuilder(args)
.UseContentRoot("c:\\<content-root>")
確定是否應(yīng)捕獲詳細(xì)錯(cuò)誤。
鍵:detailedErrors類型:布爾型(true 或 1)默認(rèn)值:false設(shè)置使用:UseSetting環(huán)境變量:ASPNETCORE_DETAILEDERRORS
啟用(或當(dāng)環(huán)境設(shè)置為 Development )時(shí),應(yīng)用捕獲詳細(xì)的異常。
C#
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.DetailedErrorsKey, "true")
設(shè)置應(yīng)用的環(huán)境。
鍵:環(huán)境類型:string默認(rèn)值:生產(chǎn)設(shè)置使用:UseEnvironment環(huán)境變量:ASPNETCORE_ENVIRONMENT
環(huán)境可以設(shè)置為任何值。 框架定義的值包括 Development``Staging 和 Production。 值不區(qū)分大小寫。 默認(rèn)情況下,從 ASPNETCORE_ENVIRONMENT 環(huán)境變量讀取環(huán)境。 使用 Visual Studio 時(shí),可能會(huì)在 launchSettings.json 文件中設(shè)置環(huán)境變量。 有關(guān)更多信息,請(qǐng)參見(jiàn)在 ASP.NET Core 中使用多個(gè)環(huán)境。
C#
WebHost.CreateDefaultBuilder(args)
.UseEnvironment(EnvironmentName.Development)
設(shè)置應(yīng)用的承載啟動(dòng)程序集。
鍵:hostingStartupAssemblies類型:string默認(rèn)值:空字符串設(shè)置使用:UseSetting環(huán)境變量:ASPNETCORE_HOSTINGSTARTUPASSEMBLIES
承載啟動(dòng)程序集的以分號(hào)分隔的字符串在啟動(dòng)時(shí)加載。
雖然配置值默認(rèn)為空字符串,但是承載啟動(dòng)程序集會(huì)始終包含應(yīng)用的程序集。 提供承載啟動(dòng)程序集時(shí),當(dāng)應(yīng)用在啟動(dòng)過(guò)程中生成其公用服務(wù)時(shí)將它們添加到應(yīng)用的程序集加載。
C#
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2")
設(shè)置 HTTPS 重定向端口。 用于強(qiáng)制實(shí)施 HTTPS。
鍵:https_port;類型:字符串; 默認(rèn)值:未設(shè)置默認(rèn)值。 設(shè)置使用:UseSetting 環(huán)境變量:ASPNETCORE_HTTPS_PORT
C#
WebHost.CreateDefaultBuilder(args)
.UseSetting("https_port", "8080")
承載啟動(dòng)程序集的以分號(hào)分隔的字符串在啟動(dòng)時(shí)排除。
鍵:hostingStartupExcludeAssemblies類型:string默認(rèn)值:空字符串設(shè)置使用:UseSetting環(huán)境變量:ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES
C#
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2")
指示主機(jī)是否應(yīng)該偵聽(tīng)使用 WebHostBuilder 配置的 URL,而不是使用 IServer 實(shí)現(xiàn)配置的 URL。
鍵:preferHostingUrls類型:布爾型(true 或 1)默認(rèn)值:true設(shè)置使用:PreferHostingUrls環(huán)境變量:ASPNETCORE_PREFERHOSTINGURLS
C#
WebHost.CreateDefaultBuilder(args)
.PreferHostingUrls(false)
阻止承載啟動(dòng)程序集自動(dòng)加載,包括應(yīng)用的程序集所配置的承載啟動(dòng)程序集。 有關(guān)更多信息,請(qǐng)參見(jiàn)在 ASP.NET Core 中使用承載啟動(dòng)程序集。
鍵:preventHostingStartup類型:布爾型(true 或 1)默認(rèn)值:false設(shè)置使用:UseSetting環(huán)境變量:ASPNETCORE_PREVENTHOSTINGSTARTUP
C#
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.PreventHostingStartupKey, "true")
指示 IP 地址或主機(jī)地址,其中包含服務(wù)器應(yīng)針對(duì)請(qǐng)求偵聽(tīng)的端口和協(xié)議。
鍵:urls類型:string默認(rèn): http://localhost:5000設(shè)置使用:UseUrls環(huán)境變量:ASPNETCORE_URLS
設(shè)置為服務(wù)器應(yīng)響應(yīng)的以分號(hào)分隔 (;) 的 URL 前綴列表。 例如 http://localhost:123。 使用“*”指示服務(wù)器應(yīng)針對(duì)請(qǐng)求偵聽(tīng)的使用特定端口和協(xié)議(例如 http://*:5000)的 IP 地址或主機(jī)名。 協(xié)議(http:// 或 https://)必須包含每個(gè) URL。 不同的服務(wù)器支持的格式有所不同。
C#
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")
Kestrel 具有自己的終結(jié)點(diǎn)配置 API。 有關(guān)更多信息,請(qǐng)參見(jiàn)ASP.NET Core 中的 Kestrel Web 服務(wù)器實(shí)現(xiàn)。
指定等待 Web 主機(jī)關(guān)閉的時(shí)長(zhǎng)。
鍵:shutdownTimeoutSeconds類型:int默認(rèn)值:5設(shè)置使用:UseShutdownTimeout環(huán)境變量:ASPNETCORE_SHUTDOWNTIMEOUTSECONDS
雖然鍵使用 UseSetting 接受 int(例如 .UseSetting(WebHostDefaults.ShutdownTimeoutKey, "10")),但是 UseShutdownTimeout 擴(kuò)展方法采用 TimeSpan。
在超時(shí)時(shí)間段中,托管:
如果在所有托管服務(wù)停止之前就達(dá)到了超時(shí)時(shí)間,則會(huì)在應(yīng)用關(guān)閉時(shí)會(huì)終止剩余的所有活動(dòng)的服務(wù)。即使沒(méi)有完成處理工作,服務(wù)也會(huì)停止。 如果停止服務(wù)需要額外的時(shí)間,請(qǐng)?jiān)黾映瑫r(shí)時(shí)間。
C#
WebHost.CreateDefaultBuilder(args)
.UseShutdownTimeout(TimeSpan.FromSeconds(10))
確定要在其中搜索 Startup 類的程序集。
鍵:startupAssembly類型:string默認(rèn)值:應(yīng)用的程序集設(shè)置使用:UseStartup環(huán)境變量:ASPNETCORE_STARTUPASSEMBLY
按名稱(string)或類型(TStartup)的程序集可以引用。 如果調(diào)用多個(gè) UseStartup 方法,優(yōu)先選擇最后一個(gè)方法。
C#
WebHost.CreateDefaultBuilder(args)
.UseStartup("StartupAssemblyName")
C#
WebHost.CreateDefaultBuilder(args)
.UseStartup<TStartup>()
設(shè)置應(yīng)用的靜態(tài)資產(chǎn)的相對(duì)路徑。
鍵:webroot類型:string默認(rèn)值:如果未指定,默認(rèn)值是“(Content Root)/wwwroot”(如果該路徑存在)。 如果該路徑不存在,則使用無(wú)操作文件提供程序。設(shè)置使用:UseWebRoot環(huán)境變量:ASPNETCORE_WEBROOT
C#
WebHost.CreateDefaultBuilder(args)
.UseWebRoot("public")
使用配置可以配置 Web 主機(jī)。 在下面的示例中,主機(jī)配置是根據(jù)需要在 hostsettings.json 文件中指定。 命令行參數(shù)可能會(huì)重寫從 hostsettings.json 文件加載的任何配置。 生成的配置(在 config中)用于通過(guò) UseConfiguration 配置主機(jī)。 IWebHostBuilder 配置會(huì)添加到應(yīng)用配置中,但反之不亦然—ConfigureAppConfiguration 不影響 IWebHostBuilder 配置。
先用 hostsettings.json config 重寫 UseUrls 提供的配置,再用命令行參數(shù) config:
C#
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hostsettings.json", optional: true)
.AddCommandLine(args)
.Build();
return WebHost.CreateDefaultBuilder(args)
.UseUrls("http://*:5000")
.UseConfiguration(config)
.Configure(app =>
{
app.Run(context =>
context.Response.WriteAsync("Hello, World!"));
});
}
}
hostsettings.json:
JSON
{
urls: "http://*:5005"
}
備注
UseConfiguration 擴(kuò)展方法當(dāng)前不能分析由 GetSection 返回的配置部分(例如 .UseConfiguration(Configuration.GetSection("section"))。 GetSection 方法將配置鍵篩選到所請(qǐng)求的部分,但將節(jié)名稱保留在鍵上(例如 section:urls、section:environment)。 UseConfiguration 方法需要鍵來(lái)匹配 WebHostBuilder 鍵(例如 urls、environment)。 鍵上存在的節(jié)名稱阻止節(jié)的值配置主機(jī)。 將在即將發(fā)布的版本中解決此問(wèn)題。 有關(guān)詳細(xì)信息和解決方法,請(qǐng)參閱將配置節(jié)傳入到 WebHostBuilder.UseConfiguration 使用完整的鍵。
UseConfiguration 只將所提供的 IConfiguration 中的密鑰復(fù)制到主機(jī)生成器配置中。 因此,JSON、INI 和 XML 設(shè)置文件的設(shè)置 reloadOnChange: true 沒(méi)有任何影響。
若要指定在特定的 URL 上運(yùn)行的主機(jī),所需的值可以在執(zhí)行 dotnet 運(yùn)行時(shí)從命令提示符傳入。 命令行參數(shù)重寫 hostsettings.json 文件中的 urls 值,且服務(wù)器偵聽(tīng)端口 8080:
console
dotnet run --urls "http://*:8080"
運(yùn)行
Run 方法啟動(dòng) Web 應(yīng)用并阻止調(diào)用線程,直到關(guān)閉主機(jī):
C#
host.Run();
Start
通過(guò)調(diào)用 Start 方法以非阻止方式運(yùn)行主機(jī):
C#
using (host)
{
host.Start();
Console.ReadLine();
}
如果 URL 列表傳遞給 Start 方法,該列表偵聽(tīng)指定的 URL:
C#
var urls = new List<string>()
{
"http://*:5000",
"http://localhost:5001"
};
var host = new WebHostBuilder()
.UseKestrel()
.UseStartup<Startup>()
.Start(urls.ToArray());
using (host)
{
Console.ReadLine();
}
應(yīng)用可以使用通過(guò)靜態(tài)便捷方法預(yù)配置的 CreateDefaultBuilder 默認(rèn)值初始化并啟動(dòng)新的主機(jī)。 這些方法在沒(méi)有控制臺(tái)輸出的情況下啟動(dòng)服務(wù)器,并使用 WaitForShutdown 等待中斷(Ctrl-C/SIGINT 或 SIGTERM):
Start(RequestDelegate app)
從 RequestDelegate 開(kāi)始:
C#
using (var host = WebHost.Start(app => app.Response.WriteAsync("Hello, World!")))
{
Console.WriteLine("Use Ctrl-C to shutdown the host...");
host.WaitForShutdown();
}
在瀏覽器中向 http://localhost:5000 發(fā)出請(qǐng)求,接收響應(yīng)“Hello World!” WaitForShutdown 受到阻止,直到發(fā)出中斷(Ctrl-C/SIGINT 或 SIGTERM)。 應(yīng)用顯示 Console.WriteLine 消息并等待 keypress 退出。
Start(string url, RequestDelegate app)
從 URL 和 RequestDelegate 開(kāi)始:
C#
using (var host = WebHost.Start("http://localhost:8080", app => app.Response.WriteAsync("Hello, World!")))
{
Console.WriteLine("Use Ctrl-C to shutdown the host...");
host.WaitForShutdown();
}
生成與 Start(RequestDelegate app) 相同的結(jié)果,除非應(yīng)用在 http://localhost:8080 上響應(yīng)。
Start(Action<IRouteBuilder> routeBuilder)
使用 IRouteBuilder 的實(shí)例 (Microsoft.AspNetCore.Routing) 用于路由中間件:
C#
using (var host = WebHost.Start(router => router
.MapGet("hello/{name}", (req, res, data) =>
res.WriteAsync($"Hello, {data.Values["name"]}!"))
.MapGet("buenosdias/{name}", (req, res, data) =>
res.WriteAsync($"Buenos dias, {data.Values["name"]}!"))
.MapGet("throw/{message?}", (req, res, data) =>
throw new Exception((string)data.Values["message"] ?? "Uh oh!"))
.MapGet("{greeting}/{name}", (req, res, data) =>
res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}!"))
.MapGet("", (req, res, data) => res.WriteAsync("Hello, World!"))))
{
Console.WriteLine("Use Ctrl-C to shutdown the host...");
host.WaitForShutdown();
}
該示例中使用以下瀏覽器請(qǐng)求:
請(qǐng)求 | 響應(yīng) |
---|---|
http://localhost:5000/hello/Martin | Hello, Martin! |
http://localhost:5000/buenosdias/Catrina | Buenos dias, Catrina! |
http://localhost:5000/throw/ooops! | 使用“ooops!”字符串引發(fā)異常 |
http://localhost:5000/throw | 使用“Uh oh!”字符串引發(fā)異常 |
http://localhost:5000/Sante/Kevin | Sante, Kevin! |
http://localhost:5000 | Hello World! |
WaitForShutdown 受到阻止,直到發(fā)出中斷(Ctrl-C/SIGINT 或 SIGTERM)。 應(yīng)用顯示 Console.WriteLine 消息并等待 keypress 退出。
Start(string url, Action<IRouteBuilder> routeBuilder)
使用 URL 和 IRouteBuilder 實(shí)例:
C#
using (var host = WebHost.Start("http://localhost:8080", router => router
.MapGet("hello/{name}", (req, res, data) =>
res.WriteAsync($"Hello, {data.Values["name"]}!"))
.MapGet("buenosdias/{name}", (req, res, data) =>
res.WriteAsync($"Buenos dias, {data.Values["name"]}!"))
.MapGet("throw/{message?}", (req, res, data) =>
throw new Exception((string)data.Values["message"] ?? "Uh oh!"))
.MapGet("{greeting}/{name}", (req, res, data) =>
res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}!"))
.MapGet("", (req, res, data) => res.WriteAsync("Hello, World!"))))
{
Console.WriteLine("Use Ctrl-C to shut down the host...");
host.WaitForShutdown();
}
生成與 Start(Action<IRouteBuilder> routeBuilder) 相同的結(jié)果,除非應(yīng)用在 http://localhost:8080上響應(yīng)。
StartWith(Action<IApplicationBuilder> app)
提供委托以配置 IApplicationBuilder:
C#
using (var host = WebHost.StartWith(app =>
app.Use(next =>
{
return async context =>
{
await context.Response.WriteAsync("Hello World!");
};
})))
{
Console.WriteLine("Use Ctrl-C to shut down the host...");
host.WaitForShutdown();
}
在瀏覽器中向 http://localhost:5000 發(fā)出請(qǐng)求,接收響應(yīng)“Hello World!” WaitForShutdown 受到阻止,直到發(fā)出中斷(Ctrl-C/SIGINT 或 SIGTERM)。 應(yīng)用顯示 Console.WriteLine 消息并等待 keypress 退出。
StartWith(string url, Action<IApplicationBuilder> app)
提供 URL 和委托以配置 IApplicationBuilder:
C#
using (var host = WebHost.StartWith("http://localhost:8080", app =>
app.Use(next =>
{
return async context =>
{
await context.Response.WriteAsync("Hello World!");
};
})))
{
Console.WriteLine("Use Ctrl-C to shut down the host...");
host.WaitForShutdown();
}
生成與 StartWith(Action<IApplicationBuilder> app) 相同的結(jié)果,除非應(yīng)用在 http://localhost:8080 上響應(yīng)。
IHostingEnvironment 接口提供有關(guān)應(yīng)用的 Web 承載環(huán)境的信息。 使用構(gòu)造函數(shù)注入獲取 IHostingEnvironment 以使用其屬性和擴(kuò)展方法:
C#
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
}
}
基于約定的方法可以用于在啟動(dòng)時(shí)基于環(huán)境配置應(yīng)用。 或者,將 IHostingEnvironment 注入到 Startup 構(gòu)造函數(shù)用于 ConfigureServices:
C#
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;
}
}
備注
除了 IsDevelopment 擴(kuò)展方法,IHostingEnvironment 提供 IsStaging、IsProduction 和 IsEnvironment(string environmentName) 方法。 有關(guān)更多信息,請(qǐng)參見(jiàn)在 ASP.NET Core 中使用多個(gè)環(huán)境。
IHostingEnvironment 服務(wù)還可以直接注入到 Configure 方法以設(shè)置處理管道:
C#
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;
}
創(chuàng)建自定義中間件時(shí)可以將 IHostingEnvironment 注入 Invoke 方法:
C#
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;
}
IApplicationLifetime 允許后啟動(dòng)和關(guān)閉活動(dòng)。 接口上的三個(gè)屬性是用于注冊(cè) Action 方法(用于定義啟動(dòng)和關(guān)閉事件)的取消標(biāo)記。
取消標(biāo)記 | 觸發(fā)條件 |
---|---|
ApplicationStarted | 主機(jī)已完全啟動(dòng)。 |
ApplicationStopped | 主機(jī)正在完成正常關(guān)閉。 應(yīng)處理所有請(qǐng)求。 關(guān)閉受到阻止,直到完成此事件。 |
ApplicationStopping | 主機(jī)正在執(zhí)行正常關(guān)閉。 仍在處理請(qǐng)求。 關(guān)閉受到阻止,直到完成此事件。 |
C#
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 請(qǐng)求應(yīng)用終止。 以下類在調(diào)用類的 Shutdown 方法時(shí)使用 StopApplication 正常關(guān)閉應(yīng)用:
C#
public class MyClass
{
private readonly IApplicationLifetime _appLifetime;
public MyClass(IApplicationLifetime appLifetime)
{
_appLifetime = appLifetime;
}
public void Shutdown()
{
_appLifetime.StopApplication();
}
}
如果應(yīng)用環(huán)境為“開(kāi)發(fā)”,則 CreateDefaultBuilder 將 ServiceProviderOptions.ValidateScopes 設(shè)為 true。
若將 ValidateScopes 設(shè)為 true,默認(rèn)服務(wù)提供程序會(huì)執(zhí)行檢查來(lái)驗(yàn)證以下內(nèi)容:
調(diào)用 BuildServiceProvider 時(shí),會(huì)創(chuàng)建根服務(wù)提供程序。 在啟動(dòng)提供程序和應(yīng)用時(shí),根服務(wù)提供程序的生存期對(duì)應(yīng)于應(yīng)用/服務(wù)的生存期,并在關(guān)閉應(yīng)用時(shí)釋放。
有作用域的服務(wù)由創(chuàng)建它們的容器釋放。 如果作用域創(chuàng)建于根容器,則該服務(wù)的生存會(huì)有效地提升至單一實(shí)例,因?yàn)楦萜髦粫?huì)在應(yīng)用/服務(wù)關(guān)閉時(shí)將其釋放。 驗(yàn)證服務(wù)作用域,將在調(diào)用 BuildServiceProvider 時(shí)收集這類情況。
若要始終驗(yàn)證作用域(包括在生存環(huán)境中驗(yàn)證),請(qǐng)使用主機(jī)生成器上的 UseDefaultServiceProvider配置 ServiceProviderOptions:
C#
WebHost.CreateDefaultBuilder(args)
.UseDefaultServiceProvider((context, options) => {
options.ValidateScopes = true;
})
更多建議: