翻譯自 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-5.0
ASP.NET Core 應用程式配置和啟動一個 Host。Host 負責應用程式的啟動和生命週期的管理。至少的,Host 配置一個伺服器和一個請求處理管道。Host 也會設定日誌,依賴注入和配置。
這篇文章覆蓋了 Web Host,任然是隻是向後相容可用。 Generic Host 推薦用於所有型別的應用程式。
配置一個 Host
使用 IWebHostBuilder 的例項建立一個 Host。一般會在應用程式的入口點 Main 方法中建立。
在工程模板中,Main 方法位於 Program.cs 中。典型的應用程式呼叫 CreateDefaultBuilder 啟動配置一個 Host:
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 的是在一個叫做 CreateWebHostBuilder 的方法中,這個方法從 Main 中分離出來,在 Main 方法中在 builder 物件上呼叫 Run 方法。這中分離是有必須的,如果你使用了 Entity Framework Core tools。這個工具期望找到一個 CreateWebHostBuilder 方法,以便能不必執行應用程式就能夠在設計的時候配置 Host。一種途徑是實現介面 IDesignTimeDbContextFactory。更多資訊,檢視 Design-time DbContext Creation。
CreateDefaultBuilder 執行了以下任務:
- 使用應用程式的託管配置的應用程式提供器配置 Kestrel 伺服器作為 web 伺服器。Kestrel 伺服器預設選項,檢視 Configure options for the ASP.NET Core Kestrel web server。
- 設定 content root 為 Directory.GetCurrentDirectory 返回的路徑值
- 從以下地方載入主機配置(host configuration)
字首為 ASPNETCORE_ 的環境變數(例如,ASPNETCORE_ENVIRONMENT)
命令列引數 - 按照下面的順序載入應用程式配置
appsetting.json
appsetting.{Environment}.json
User secrets 當應用程式使用入口程式集執行在 Development 環境時
環境變數
命令列引數 - 為控制檯和除錯輸出配置日誌(logging)。日誌包括在 appsetting.json 或者 appsetting.{Environment}.json 檔案中配置區域配置的日誌過濾(log filtering)規則。
- 當 ASP.NET Core Module 執行在 IIS 之後,CreateDefaultBuilder 會使能 IIS 整合(IIS Integration),配置了應用程式基本地址和埠。IIS 整合也會配置應用程式捕獲啟動錯誤(capture startup errors)。關於 IIS 預設配置,檢視 Host ASP.NET Core on Windows with IIS。
- 如果應用程式環境為 Development,設定 ServiceProviderOptions.ValidateScopes 為 true。更多資訊,檢視 Scope validation。
CreateDefaultBuilder 定義的配置可以被覆蓋和使用 ConfigureAppConfiguration,ConfigureLogging 和其它方法及 IWebHostBuilder 的擴充套件方法擴充套件。下面是幾個例子:
- ConfigureAppConfiguration 用來為應用程式指定額外的 IConfiguration。下面的 ConfigureAppConfiguration 呼叫新增了一個代理去包含在 appsettings.xml 檔案中的應用程式的配置。ConfigureAppConfiguration 可能會呼叫多次。注意這個配置並不應用到主機(例如,伺服器 URLs 或者 環境)。檢視 Host configuration values 部分。
WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true); }) ...
- 下面的 ConfigureLogging 呼叫新增一個代理去配置最小的logging level (SetMinimumLevel) 為 LogLevel.Warning。這個設定覆蓋了appsettings.Development.json (LogLevel.Debug) 和 appsettings.Production.json (LogLevel.Error) 裡面通過 CreateDefaultBuilder 配置的設定。ConfigureLogging 可能會呼叫多次。
WebHost.CreateDefaultBuilder(args) .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Warning); }) ...
- 下面的 ConfigureKestrel 的呼叫覆蓋了 Kestrel 通過 CreateDefaultBuilder 配置的預設的 Limits.MaxRequestBodySize 30,000,000 位元組:
WebHost.CreateDefaultBuilder(args) .ConfigureKestrel((context, options) => { options.Limits.MaxRequestBodySize = 20000000; });
content root 決定了 Host 在哪裡搜尋內容檔案,例如 MVC 檢視檔案。當應用程式從工程根目錄啟動的時候,工程根目錄被用作內容根目錄。這在 Visual Studio 和 dotnet new templates 預設使用。
更多關於應用程式配置的資訊,檢視 Configuration in ASP.NET Core。
注意
作為一種使用靜態 CreateDefaultBuilder 方法的途徑,從 WebHostBuilder 建立一個 Host 在 ASP.NET Core 2.x 中是受支援的。
當設定一個主機的時候,可以提供 Configure 和 ConfigureServices 這兩個方法。如果一個 Startup 方法被指定了,它必須定義 Configure 方法。更多資訊,檢視 App startup in ASP.NET Core 。多次呼叫 ConfigureServices 將會附加到另外一個上面。在 WebHostBuilder 上多次呼叫 Configure 或者 UseStartup 將會替換之前的設定。
Host configuration values
WebHostBuilder 依賴下面的方法設定主機配置值:
- Host builder configuration,包含格式為 ASPNETCORE_{configurationKey} 的環境變數。例如,ASPNETCORE_ENVIRONMENT。
- 擴充套件,例如 UseContentRoot 和 UseConfiguration (檢視 Override configuration 部分)
- UseSetting 和相關的鍵。當使用 UseSetting 設定值得時候,值被設定為字串而忽略它的型別。
主機使用最後設定值得選項。更多資訊檢視,Override configuration。
Application Key (Name)
當 UseStartup 或者 Configure 在主機構造方法中呼叫的時候,IWebHostEnvironment.ApplicationName 屬性會自動設定。值被設定為包含應用程式入口點的程式集的名稱。顯式的設定,可以使用 WebHostDefaults.ApplicationKey:
Key: applicationName
Type: string
Default: 包含應用程式入口點程式集的名稱
Set using: UseSetting
Environment variable: ASPNETCORE_APPLICATIONNAME
WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")
Capture Startup Errors
設定捕獲啟動錯誤的控制
Key: captureStartupErrors
Type: bool (true or 1)
Default: 預設為 false,除非應用程式使用 Kestrel 執行在 IIS 之後,這時預設是 true
Set using: CaptureStartupErrors
Environment variable: ASPNETCORE_CAPTURESTARTUPERRORS
當設定為 false 時,啟動過程中的錯誤會導致主機退出。當設定為 true 時,主機會捕獲啟動過程中的異常,並且試圖啟動伺服器。
WebHost.CreateDefaultBuilder(args) .CaptureStartupErrors(true)
Content root
這個設定決定了 ASP.NET Core 開始搜尋內容檔案的位置。
Key: contentRoot
Type: string
Default: 預設是應用程式程式集所在的目錄
Set using: UseContentRoot
Environment variable: ASPNETCORE_CONTENTROOT
content root 也被用作 web root 的基本路徑。如果 content root 路徑不存在,主機就會啟動失敗。
WebHost.CreateDefaultBuilder(args) .UseContentRoot("c:\\<content-root>")
更多資訊,請檢視:
Detailed Errors
決定是否應該詳細錯誤資訊
Key: detailedErrors
Type: bool (treu 或者 1)
Default: false
Set using: UseSetting
Environment variable: ASPNETCORE_DETAILEDERRORS
當使能的時候(或者 Environment 被設定為 Development 的時候),應用程式會捕獲異常詳細資訊。
WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.DetailedErrorsKey, "true")
Environment
設定應用程式環境
Key: environment
Type: string
Default: Production
Set using: UseEnvironment
Environment variable: ASPNETCORE_ENVIRONMENT
environmenmt 可以被設定為任意的值。框架定義的值包括 Development,Staging 和 Production。值不區分大小寫。預設的,Environment 從 ASPNETCORE_ENVIRONMENT 環境變數中讀取。當使用 Visual Studio 時,環境變數可能在 lauchSetting.json 檔案中設定。更過資訊,請檢視: Use multiple environments in ASP.NET Core。
WebHost.CreateDefaultBuilder(args)
.UseEnvironment(EnvironmentName.Development)
Hosting Startup Assemblies
設定應用程式託管啟動程式集
Key: hostingStartupAssemblies
Type: string
Default: Empty string
Set using: UseSetting
Environment variable: ASPNETCORE_HOSTINGSTARTUPASSEMBLIES
以逗號分隔的字串,啟動時載入的託管的啟動程式集
儘管配置值被設定為空字串,託管程式集總是包含應用程式程式集。當提供了託管啟動程式集,它們在應用程式啟動時建立公共服務時被新增到應用程式程式集。
WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2")
HTTPs Port
設定 HTTPS 重定向埠。使用 enforcing HTTPS。
Key: https_port
Type: string
Defalut: 預設無設定
Set using: UseSetting
Environment variable: ASPNETCORE_HTTPS_PORT
WebHost.CreateDefaultBuilder(args) .UseSetting("https_port", "8080")
Hosting Startup Exclude Assemblies
冒號分隔的字串,啟動時排除託管啟動程式集
Key: hostingStartupExcludeAssemblies
Type: string
Default: Empty string
Set using: UseSetting
Environment variable: ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES
WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2")
Prefer Hosting URLs
表明主機是否應該在使用 WebHostBuilder 配置的 URLs 上監聽,而不是 IServer 實現配置的 URLs
Key: preferHostingUrls
Type: bool (true 或者 1)
Default: true
Set using: PreferHostingUrls
Environment variable: ASPNETCORE_PREFERHOSTINGURLS
WebHost.CreateDefaultBuilder(args) .PreferHostingUrls(false)
Prevent Hosting Startup
阻止自動載入託管啟動程式集,包括應用程式程式集配置的託管啟動程式集。更多資訊檢視,Use hosting startup assemblies in ASP.NET Core。
Key: preventHostingStartup
Type: bool (true 或者 1)
Default: false
Set using: UseSetting
Environment variable: ASPNETCORE_PREVENTHOSTINGSTARTUP
WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.PreventHostingStartupKey, "true")
Server URLs
表明帶有埠和協議的 IP 地址或者主機地址是否應該被伺服器監聽請求
Key: urls
Type: string
Default: http://localhost:5000
Set using: UseUrls
Environment variable: ASPNETCORE_URLS
設定一組伺服器應該響應的冒號(;)分隔的 URL 字首。例如,http://localhost:123。使用 "*" 表明伺服器是否應該監聽任意使用特定埠和協議(例如,http://*:5000)的 IP 地址或者主機地址。協議 (http:// 或者 https://) 必須包含在每一個 URL 中。支援的格式因伺服器不同而不同。
WebHost.CreateDefaultBuilder(args) .UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")
Kestrel 有它自己的 endpoint 配置 API。更多資訊檢視,Configure endpoints for the ASP.NET Core Kestrel web server。
Shutdown Timeout
指定等待 Web Host 關閉的超時時間
Key: shutdownTimeoutSeconds
Type: int
Default: 5
Set using: UseShutdownTimeout
Environment variable: ASPNETCORE_SHUTDOWNTIMEOUTSECONDS
儘管使用 UseSetting 可以接受鍵為 int 的值(例如,.UseSetting(WebHostDefaults.ShutdownTimeoutKey,"10")),UseShutdownTimeout 帶有 TimeSpan 引數。
在超時時間內,主機會:
- 觸發 IApplicationLifetime.ApplicationStopping
- 嘗試停止託管的服務,日誌記錄任何服務停止失敗的錯誤
如果在所有服務停止之前超時了,任何活動的服務在應用程式關閉時都會停止。即使服務沒有完成處理也會被停止。如果服務需要更多的時間去停止,增加超時時間。
WebHost.CreateDefaultBuilder(args) .UseShutdownTimeout(TimeSpan.FromSeconds(10))
Startup Assembly
決定搜尋 Startup 類的程式集
Key: startupAssembly
Type: string
Default: 應用程式程式集
Set using: UseStartup
Environment variable: ASPNETCORE_STARTUPASSEMBLY
可以指定程式的名稱(string)或者型別 (TStartup)。如果多個 UseStartup 方法被呼叫,則最後一個優先順序最高:
WebHost.CreateDefaultBuilder(args) .UseStartup("StartupAssemblyName")
WebHost.CreateDefaultBuilder(args)
.UseStartup<TStartup>()
Web root
設定應用程式靜態資源的相對路徑
Key: webroot
Type: string
Default: 預設是 wwwroot。路基 {contentroot}/wwwroot 必須存在。如果路徑不存在,一個 no-op 檔案提供器將被使用。
WebHost.CreateDefaultBuilder(args) .UseWebRoot("public")
更多資訊檢視:
覆蓋配置
使用 Configuration 配置 Web Host。在下面的例子中,host 配置在 hostsetting.json 檔案中是可選指定的。任何從 hostsetting.json 檔案中載入的配置可能會被命令列引數覆蓋。編譯的配置(in config)使用 UseConfiguration 來配置主機。IWebHostBuilder 配置被新增到應用程式配置中,但是相反的就不是,ConfigureAppConfigureation 不會影響 IWebHostBuilder 配置。
覆蓋 UseUrls 提供的配置優先使用 hostsettings.json 配置,其次是命令列引數配置:
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:
{ urls: "http://*:5005" }
注意
UseConfiguration 只會複製 IConfiguration 提供的鍵值到 host builder 配置。因此,設定 reloadOnChange: true 為 JSON,INI,和 XML 設定檔案沒有影響。
指定主機在一個特定的 URL 上執行,期望的值可以在執行 dotnet run 時命令列提示中傳入。命令列引數覆蓋了來自 hostsettings.json 中的 urls 值,伺服器在 8080 埠監聽:
dotnet run --urls "http://*:8080"
管理 Host
Run
Run 方法啟動 web 應用程式並阻塞呼叫執行緒直到 Host 關閉:
host.Run();
Start
通過呼叫它的 Start 方法以 non-blocking 方式執行 Host:
using (host) { host.Start(); Console.ReadLine(); }
如果一組 URLs 傳遞給 Start 方法,它就會監聽這組指定的 URLs:
var urls = new List<string>() { "http://*:5000", "http://localhost:5001" }; var host = new WebHostBuilder() .UseKestrel() .UseStartup<Startup>() .Start(urls.ToArray()); using (host) { Console.ReadLine(); }
應用程式可以使用預設值的預設 CreateDefaultBuilder 使用一個靜態約定的方法初始化和啟動一個新的 Host。這些方法啟動伺服器時沒有控制檯輸出,使用 WaitForShutdown 等待終止(Ctrl-C/SIGINT 或者 SIGTERM):
Start(RequestDelegate app)
使用 RequestDelegate 啟動:
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 接收到 "Hello World!" 響應,WaitForShutdown 阻塞了直到一個結束訊號 (Ctrl-C/SIGINT 或者 SIGTERM) 出現。應用程式顯示了 Console.WriteLine 資訊,等待按鍵退出。
Start(string url, RequestDelegate app)
使用一個 URL 和 RequestDelegate 啟動應用程式:
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) 生成同樣的結果,期望應用程式在 http://localhost:8080 上響應。
Start(Action <IRouteBuilder> routerBuilder)
使用 IRouteBuilder (Microsoft.AspNetCore.Routing) 的例項使用 routing 中介軟體:
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(); }
對上面的示例使用下面的瀏覽器請求:
Request | Response |
http://localhost:5000/hello/Martin | Hello,Martin! |
http://localhost:5000/buenosdias/Catrina | Buenos dias,Catrina! |
http://localhost:5000/throw/ooops! | Throw an exception with string "ooops!" |
http://localhost:5000/throw | Throw an exception with string "Uh oh!" |
http://localhost:5000/Sante/Kevin | Sante,Kevin! |
http://localhost:5000 | Hello World! |
WaitForShutdown 阻塞直到結束訊號(Ctrl-C/SIGINT 或者 SIGTERM)出現。應用程式顯示 Console.WriteLine 資訊,等待按鍵按下退出。
Start(string url, Action<IRouteBuilder> routeBuilder)
使用 URL 和 IRouterBuilder 例項:
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) 相同的結果,期望應用程式在 http://localhost:8080 上響應。
StartWith(Action<IApplicationBuilder> app)
提供一個代理配置一個 IApplicationBuilder:
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 接收到 "Hello World!" 響應,WaitForShutdown 阻塞直到一個結束訊號(Ctrl-C/SIGINT 或者 SIGTERM)發出。應用程式顯示了 Console.WriteLine 資訊,等待按鍵按下退出。
StartWith(string url, Action<IApplicationBuilder> app)
提供一個 url 和一個代理配置 IApplicationBuilder:
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<IApplicatonBuilder> app) 相同的結果,期望在應用程式在 http://localhost:8080 上響應。
IWebHostEnvironment interface
IWebHostEnvironment 介面提供了關於應用程式 web 託管環境的資訊。使用 constructor injection 訪問 IWebHostEnvironment 保證使用它的屬性和擴充套件方法:
public class CustomFileReader { private readonly IWebHostEnvironment _env; public CustomFileReader(IWebHostEnvironment env) { _env = env; } public string ReadFile(string filePath) { var fileProvider = _env.WebRootFileProvider; // Process the file here } }
一個 convention-based approach 可以基於環境在啟動時用來配置應用程式。或者,在 ConfigureServices 中將 IWebHostEnvironment 注入到 Startup 構造方法使用:
public class Startup { public Startup(IWebHostEnvironment env) { HostingEnvironment = env; } public IWebHostEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services) { if (HostingEnvironment.IsDevelopment()) { // Development configuration } else { // Staging/Production configuration } var contentRootPath = HostingEnvironment.ContentRootPath; } }
注意
除了 IsDevelopment 擴充套件方法外,IWebHostEnvironment 提供了 IsStaging,IsProduction 和 IsEnvironment(string environment) 方法。更多資訊檢視,Use multiple environments in ASP.NET Core。
IWebHostEnvironment 服務也可以直接注入到 Configure 方法用來設定處理管道:
public void Configure(IApplicationBuilder app, IWebHostEnvironment 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; }
當建立自定義中介軟體(middleware)的時候,IWebHostEnvironment 可以被注入到 Invoke 方法:
IHostApplicationLifetime interface
IHostApplicationLifetime 允許 post-startup 和 關閉。介面的三個屬性是取消令牌,用來註冊定義啟動和關閉時間的Action 方法。
Cancellation Token | Triggered when... |
ApplicationStarted | 主機已經完全啟動 |
ApplicationStopped | 主機已經完全正常關閉。所有的請求應該已經處理完畢。關閉阻塞直到這個事件完成。 |
ApplicationStopping | 主機正在正常關閉。請求可能仍然正在處理。關閉阻塞直到這個事件完成。 |
public class Startup { public void Configure(IApplicationBuilder app, IHostApplicationLifetime 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 請求結束應用程式。下面的類使用 StopApplication 正常關閉應用程式當類的 Shutdown 方法被呼叫的時候:
public class MyClass { private readonly IHostApplicationLifetime _appLifetime; public MyClass(IHostApplicationLifetime appLifetime) { _appLifetime = appLifetime; } public void Shutdown() { _appLifetime.StopApplication(); } }
Scope validation
當應用程式的環境是 Development 的時候,CreateDefaultBuilder 設定 ServiceProviderOptions.ValidateScopes 為 true。
當 ValidateScopes 被設定為 true 時,預設的服務提供器執行檢查驗證:
- Scoped 服務不能直接或者間接的從根服務提供器中解析出來
- Scoped 服務不能直接或者間接的注入到單例中
根服務提供器在 BuildServiceProvider 被呼叫時建立。根服務提供器的生命週期和應用程式/伺服器的生命週期一致,當提供器和應用程式一起啟動,在應用程式關閉時釋放。
Scoped 服務由建立它的容器釋放。如果一個 scoped 服務在根容器中建立,服務的生命週期會有效的提升為單例,因為它只有在應用程/伺服器關閉的時候會釋放掉。在呼叫 BuildServiceProvider 的時候,驗證服務會捕捉這些情況。
為了在 Production 環境中總是包含 validate scopes,在 Host builer 上使用 UseDefaultServiceProvider 配置 ServiceProviderOptions:
WebHost.CreateDefaultBuilder(args) .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = true; })