ASP.NET Core Web 主機

ASP.NET Core 應用程式會設定並啟動「主機」。 主機負責應用程式啟動和存留期管理。 至少,主機會設定伺服器和要求處理管線。 主機也可以設定記錄、相依性插入和設定。

此文章涵蓋 Web 主機,而且我們僅因為回溯相容性而繼續提供它。 ASP.NET Core 範本會建立 WebApplicationBuilderWebApplication,建議用於 Web 應用程式。 如需 WebApplicationBuilderWebApplication 的詳細資訊,請參閱從 ASP.NET Core 5.0 移轉至 6.0

設定主機

使用 IWebHostBuilder 的執行個體建立主機。 這通常在應用程式的進入點執行,也就是 Program.cs 中的 Main 方法。 一般的應用程式會呼叫 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>();
}

呼叫 CreateDefaultBuilder 的程式碼位於名為 CreateWebHostBuilder 的方法中,這將它與 Main 中呼叫產生器物件上之 Run 的方法分開。 若您使用e Entity Framework Core 工具,則此分開是必要的。 工具預期找到它們可以在設計階段呼叫的 CreateWebHostBuilder 方法,以在不執行應用程式的情況下設定主機。 替代方式是實作 IDesignTimeDbContextFactory。 如需詳細資訊,請參閱設計階段 DbContext 建立

CreateDefaultBuilder 會執行下列工作:

CreateDefaultBuilder 所定義的組態可以透過 ConfigureAppConfigurationConfigureLogging,以及 IWebHostBuilder 的其他方法和擴充方法加以覆寫及擴增。 數個範例如下:

  • ConfigureAppConfiguration 用於為應用程式指定額外的 IConfiguration。 下列 ConfigureAppConfiguration 呼叫會新增委派,以在 appsettings.xml 檔案中包含應用程式組態。 可能會多次呼叫 ConfigureAppConfiguration。 請注意,此組態不適用於主機 (例如,伺服器 URL 或環境)。 請參閱主機組態值一節。

    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
        })
        ...
    
  • 下列 ConfigureLogging 呼叫會新增委派,將最低的記錄層級 (SetMinimumLevel) 設定為 LogLevel.Warning。 此設定會覆寫 CreateDefaultBuilderappsettings.Development.json (LogLevel.Debug) 和 appsettings.Production.json (LogLevel.Error) 中所作的設定。 可能會多次呼叫 ConfigureLogging

    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging => 
        {
            logging.SetMinimumLevel(LogLevel.Warning);
        })
        ...
    
  • 下列 ConfigureKestrel 呼叫會覆寫當 CreateDefaultBuilder 設定 Kestrel 時建立的預設 Limits.MaxRequestBodySize 30,000,000 位元組:

    WebHost.CreateDefaultBuilder(args)
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.MaxRequestBodySize = 20000000;
        });
    

「內容根目錄」會決定主機搜尋內容檔案 (例如 MVC 檢視檔案) 的位置。 從專案的根資料夾啟動應用程式時,會使用專案的根資料夾作為內容根目錄。 這是 Visual Studiodotnet 新範本中使用的預設值。

如需應用程式設定的詳細資訊,請參閱 ASP.NET Core 中的組態

注意

作為使用靜態 CreateDefaultBuilder 方法的替代做法,ASP.NET Core 2.x 支援從 WebHostBuilder 建立主機的方法。

設定主機時,可以提供 ConfigureConfigureServices 方法。 如果指定 Startup 類別,它必須定義 Configure 方法。 如需詳細資訊,請參閱 ASP.NET Core 中的應用程式啟動。 多次呼叫 ConfigureServices 會彼此附加。 對 WebHostBuilder 多次呼叫 ConfigureUseStartup 則會取代先前的設定。

主機組態值

WebHostBuilder 依賴下列方法來設定主機組態值:

  • 主機建立器組態,其中包含 ASPNETCORE_{configurationKey} 格式的環境變數。 例如: ASPNETCORE_ENVIRONMENT
  • UseContentRootUseConfiguration 等擴充功能 (請參閱覆寫組態一節)。
  • UseSetting 和相關聯的索引鍵。 使用 UseSetting 設定值時,此值會設定為字串,而不論其類型為何。

主機使用設定最後一個值的任何選項。 如需詳細資訊,請參閱下一節的覆寫組態

應用程式索引鍵 (名稱)

當主機建構期間呼叫 UseStartupConfigure 時,則會自動設定 IWebHostEnvironment.ApplicationName 屬性。 該值會設定為包含應用程式進入點的組件名稱。 若要明確設定值,請使用 WebHostDefaults.ApplicationKey

索引鍵:applicationName
類型string
預設:包含應用程式進入點的組件名稱。
設定使用UseSetting
環境變數ASPNETCORE_APPLICATIONNAME

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")

擷取啟動錯誤

此設定會控制啟動錯誤的擷取。

索引鍵:captureStartupErrors
類型bool (true1)
預設值:預設值為 false,除非應用程式在 IIS 後端使用 true 執行,其中預設值為 Kestrel。
設定使用CaptureStartupErrors
環境變數ASPNETCORE_CAPTURESTARTUPERRORS

當它為 false 時,啟動期間發生的錯誤會導致主機結束。 當它為 true 時,主機會擷取啟動期間的例外狀況,並嘗試啟動伺服器。

WebHost.CreateDefaultBuilder(args)
    .CaptureStartupErrors(true)

內容根目錄

此設定可決定 ASP.NET Core 開始搜尋內容檔案的位置。

索引鍵:contentRoot
類型string
預設值:預設為應用程式組件所在的資料夾。
設定使用UseContentRoot
環境變數ASPNETCORE_CONTENTROOT

內容根目錄也作為 Web 根目錄的基底路徑。 如果內容根路徑不存在,就無法啟動主機。

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

如需詳細資訊,請參閱

詳細錯誤

決定是否應該擷取詳細的錯誤。

索引鍵:detailedErrors
類型bool (true1)
預設值:false
設定使用UseSetting
環境變數ASPNETCORE_DETAILEDERRORS

啟用時 (或當 Environment 設定為 Development 時),應用程式會擷取詳細例外狀況。

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

環境

設定應用程式的環境。

索引鍵:environment
類型string
預設值:Production
設定使用UseEnvironment
環境變數ASPNETCORE_ENVIRONMENT

環境可以設定為任何值。 架構定義的值包括 DevelopmentStagingProduction。 值不區分大小寫。 根據預設,Environment 是從 ASPNETCORE_ENVIRONMENT 環境變數讀取。 使用 Visual Studio 時,可以在 launchSettings.json 檔案中設定環境變數。 如需詳細資訊,請參閱在 ASP.NET Core 中使用多個環境 (部分機器翻譯)。

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

裝載啟動組件

設定應用程式的裝載啟動組件。

索引鍵:hostingStartupAssemblies
類型string
預設值:空字串
設定使用UseSetting
環境變數ASPNETCORE_HOSTINGSTARTUPASSEMBLIES

在啟動時載入的裝載啟動組件字串,以分號分隔。

雖然設定值會預設為空字串,但裝載啟動組件一律會包含應用程式的組件。 提供裝載啟動組件時,它們會新增至應用程式的組件,以便在應用程式在啟動時建置其通用服務時載入。

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2")

HTTPS 連接埠

設定 HTTPS 重新導向連接埠。 用於強制 HTTPS

金鑰:https_port
類型string
預設值:未設定預設值。
設定使用UseSetting
環境變數ASPNETCORE_HTTPS_PORTS

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

裝載啟動排除組件

在啟動時排除以分號分隔的裝載啟動組件字串。

索引鍵:hostingStartupExcludeAssemblies
類型string
預設值:空字串
設定使用UseSetting
環境變數ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2")

偏好裝載 URL

表示主機是否應接聽使用 WebHostBuilder 設定的 URL,而不是 IServer 實作所設定的 URL。

索引鍵:preferHostingUrls
類型bool (true1)
預設值:false
設定使用PreferHostingUrls
環境變數ASPNETCORE_PREFERHOSTINGURLS

WebHost.CreateDefaultBuilder(args)
    .PreferHostingUrls(true)

防止裝載啟動

可防止自動載入裝載啟動組件,包括應用程式組件所設定的裝載啟動組件。 如需詳細資訊,請參閱在 ASP.NET Core 中使用裝載啟動組件 (部分機器翻譯)。

索引鍵preventHostingStartup
類型bool (true1)
預設值:false
設定使用UseSetting
環境變數ASPNETCORE_PREVENTHOSTINGSTARTUP

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

伺服器 URL

表示伺服器應該接聽要求的 IP 位址或主機位址,以及連接埠和通訊協定。

索引鍵:urls
類型string
預設值:http://localhost:5000
設定使用UseUrls
環境變數ASPNETCORE_URLS

設定為伺服器應該回應的 URL 前置清單,並以分號 (;) 分隔。 例如: http://localhost:123 。 使用 "*" 表示伺服器應接聽任何 IP 位址或主機名稱上的要求,並使用指定的連接埠和通訊協定 (例如,http://*:5000)。 通訊協定 (http://https://) 必須包含在每個 URL 中。 支援的格式會依伺服器而有所不同。

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

Kestrel 有它自己的端點設定 API。 如需詳細資訊,請參閱設定 ASP.NET Core Kestrel Web 伺服器的端點

關機逾時

指定等待 Web 主機關機的時間長度。

索引鍵:shutdownTimeoutSeconds
類型int
預設值:5
設定使用UseShutdownTimeout
環境變數ASPNETCORE_SHUTDOWNTIMEOUTSECONDS

雖然索引鍵接受 intUseSetting (例如 .UseSetting(WebHostDefaults.ShutdownTimeoutKey, "10")),UseShutdownTimeout 擴充方法會採用 TimeSpan

在逾時期間,裝載會:

如果在所有的託管服務停止之前逾時期限已到期,則應用程式關閉時,會停止任何剩餘的作用中服務。 即使服務尚未完成處理也會停止。 如果服務需要更多時間才能停止,請增加逾時。

WebHost.CreateDefaultBuilder(args)
    .UseShutdownTimeout(TimeSpan.FromSeconds(10))

啟動組件

決定要搜尋 Startup 類別的組件。

索引鍵:startupAssembly
類型string
預設值:應用程式的組件
設定使用UseStartup
環境變數ASPNETCORE_STARTUPASSEMBLY

可以參考依名稱 (string) 或類型 (TStartup) 的組件。 如果呼叫多個 UseStartup 方法,最後一個將會優先。

WebHost.CreateDefaultBuilder(args)
    .UseStartup("StartupAssemblyName")
WebHost.CreateDefaultBuilder(args)
    .UseStartup<TStartup>()

Web 根目錄

設定應用程式靜態資產的相對路徑。

索引鍵:webroot
類型string
預設值:預設值為 wwwroot{content root}/wwwroot 的路徑必須存在。 如果路徑不存在,則會使用無作業檔案提供者。
設定使用UseWebRoot
環境變數ASPNETCORE_WEBROOT

WebHost.CreateDefaultBuilder(args)
    .UseWebRoot("public")

如需詳細資訊,請參閱

覆寫組態

使用 Configuration 來設定 Web 主機。 在下列範例中,主機組態選擇性地指定於 hostsettings.json 檔案中。 從 hostsettings.json 檔案載入的任何設定,可以用命令列引數覆寫。 組建組態 (在 config 中) 用以使用 UseConfiguration 來設定主機。 IWebHostBuilder 設定會新增到應用程式的組態,但反之則不然 ConfigureAppConfiguration 並不會影響 IWebHostBuilder 組態。

首先使用 hostsettings.json 組態來覆寫 UseUrls 所提供的設定,其次是命令列引數:

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 複製到主機建立器的組態。 因此,為 JSON、INI 和 XML 設定檔設定 reloadOnChange: true 沒有任何作用。

若要指定主機在特定 URL 上執行,所要的值可以在執行 dotnet run 時從命令提示字元傳入。 命令列引數會覆寫 hostsettings.json 檔的 urls 值,且伺服器會接聽連接埠 8080:

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

管理主機

執行

Run 方法會啟動 Web 應用程式,並且封鎖呼叫執行緒,直到主機關閉為止:

host.Run();

啟動

藉由呼叫 Start 方法,以非封鎖方式執行主機:

using (host)
{
    host.Start();
    Console.ReadLine();
}

如果 URL 的清單傳遞至 Start 方法,它會接聽指定的 URL:

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 預設值,使用便利的靜態方法初始化並啟動新的主機。 這些方法會啟動伺服器而無主控台輸出,且在使用 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> routeBuilder)

使用 IRouteBuilder (Microsoft.AspNetCore.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 回應
http://localhost:5000/hello/Martin Hello, Martin!
http://localhost:5000/buenosdias/Catrina Buenos dias, Catrina!
http://localhost:5000/throw/ooops! 擲回例外狀況,字串為 "ooops!"
http://localhost:5000/throw 擲回例外狀況,字串為 "Un 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 和 IRouteBuilder 的執行個體:

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<IApplicationBuilder> app) 相同的結果,除了應用程式會在 http://localhost:8080 回應。

IWebHostEnvironment 介面

IWebHostEnvironment 介面提供應用程式的 Web 裝載環境相關資訊。 使用建構函式插入以取得 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
    }
}

以慣例為基礎的方法可用來根據環境在啟動時設定應用程式。 或者,將 IWebHostEnvironment 插入至 Startup 建構函式,以便用於 ConfigureServices

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 也提供 IsStagingIsProductionIsEnvironment(string environmentName) 方法。 如需詳細資訊,請參閱在 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;
}

建立自訂中介軟體時,IWebHostEnvironment 可以插入至 Invoke 方法:

public async Task Invoke(HttpContext context, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Configure middleware for Development
    }
    else
    {
        // Configure middleware for Staging/Production
    }

    var contentRootPath = env.ContentRootPath;
}

IHostApplicationLifetime 介面

IHostApplicationLifetime 允許啟動後和關機活動。 在介面上的三個屬性是用來註冊定義啟動和關閉事件之 Action 方法的取消語彙基元。

取消語彙基元 觸發時機…
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 會要求應用程式終止。 當呼叫類別的 Shutdown 方法時,下列類別使用 StopApplication 來順利關閉應用程式:

public class MyClass
{
    private readonly IHostApplicationLifetime _appLifetime;

    public MyClass(IHostApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public void Shutdown()
    {
        _appLifetime.StopApplication();
    }
}

範圍驗證

如果應用程式的環境為 [開發],則 CreateDefaultBuilder 會將 ServiceProviderOptions.ValidateScopes 設定為 true

ValidateScopes 設定為 true 時,預設服務提供者會執行檢查以確認:

  • 範圍服務不是直接或間接由根服務提供者解析。
  • 範圍服務不是直接或間接插入至單一服務。

根服務提供者會在呼叫 BuildServiceProvider 時建立。 當提供者啟動應用程式時,根服務提供者的存留期與應用程式/伺服器的存留期一致,並會在應用程式關閉時處置。

範圍服務會由建立這些服務的容器處置。 若是在根容器中建立範圍服務,因為當應用程式/伺服器關機時,服務只會由根容器處理,所以服務的存留期會提升為單一服務等級。 當呼叫 BuildServiceProvider 時,驗證服務範圍會攔截到這些情況。

若要一律驗證範圍,包括在生產環境中,請使用主機建立器上的 UseDefaultServiceProvider 來設定 ServiceProviderOptions

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

其他資源

ASP.NET Core 應用程式會設定並啟動「主機」。 主機負責應用程式啟動和存留期管理。 至少,主機會設定伺服器和要求處理管線。 主機也可以設定記錄、相依性插入和設定。

此文章涵蓋 Web 主機,而且我們僅因為回溯相容性而繼續提供它。 ASP.NET Core 範本會建立 .NET 泛型主機,建議用於所有類型的應用程式。

設定主機

使用 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>();
}

呼叫 CreateDefaultBuilder 的程式碼位於名為 CreateWebHostBuilder 的方法中,這將它與 Main 中呼叫產生器物件上之 Run 的方法分開。 若您使用e Entity Framework Core 工具,則此分開是必要的。 工具預期找到它們可以在設計階段呼叫的 CreateWebHostBuilder 方法,以在不執行應用程式的情況下設定主機。 替代方式是實作 IDesignTimeDbContextFactory。 如需詳細資訊,請參閱設計階段 DbContext 建立

CreateDefaultBuilder 會執行下列工作:

CreateDefaultBuilder 所定義的組態可以透過 ConfigureAppConfigurationConfigureLogging,以及 IWebHostBuilder 的其他方法和擴充方法加以覆寫及擴增。 數個範例如下:

  • ConfigureAppConfiguration 用於為應用程式指定額外的 IConfiguration。 下列 ConfigureAppConfiguration 呼叫會新增委派,以在 appsettings.xml 檔案中包含應用程式組態。 可能會多次呼叫 ConfigureAppConfiguration。 請注意,此組態不適用於主機 (例如,伺服器 URL 或環境)。 請參閱主機組態值一節。

    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
        })
        ...
    
  • 下列 ConfigureLogging 呼叫會新增委派,將最低的記錄層級 (SetMinimumLevel) 設定為 LogLevel.Warning。 此設定會覆寫 CreateDefaultBuilderappsettings.Development.json (LogLevel.Debug) 和 appsettings.Production.json (LogLevel.Error) 中所作的設定。 可能會多次呼叫 ConfigureLogging

    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging => 
        {
            logging.SetMinimumLevel(LogLevel.Warning);
        })
        ...
    
  • 下列 ConfigureKestrel 呼叫會覆寫當 CreateDefaultBuilder 設定 Kestrel 時建立的預設 Limits.MaxRequestBodySize 30,000,000 位元組:

    WebHost.CreateDefaultBuilder(args)
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.MaxRequestBodySize = 20000000;
        });
    

「內容根目錄」會決定主機搜尋內容檔案 (例如 MVC 檢視檔案) 的位置。 從專案的根資料夾啟動應用程式時,會使用專案的根資料夾作為內容根目錄。 這是 Visual Studiodotnet 新範本中使用的預設值。

如需應用程式設定的詳細資訊,請參閱 ASP.NET Core 中的組態

注意

作為使用靜態 CreateDefaultBuilder 方法的替代做法,ASP.NET Core 2.x 支援從 WebHostBuilder 建立主機的方法。

設定主機時,可以提供 ConfigureConfigureServices 方法。 如果指定 Startup 類別,它必須定義 Configure 方法。 如需詳細資訊,請參閱 ASP.NET Core 中的應用程式啟動。 多次呼叫 ConfigureServices 會彼此附加。 對 WebHostBuilder 多次呼叫 ConfigureUseStartup 則會取代先前的設定。

主機組態值

WebHostBuilder 依賴下列方法來設定主機組態值:

  • 主機建立器組態,其中包含 ASPNETCORE_{configurationKey} 格式的環境變數。 例如: ASPNETCORE_ENVIRONMENT
  • UseContentRootUseConfiguration 等擴充功能 (請參閱覆寫組態一節)。
  • UseSetting 和相關聯的索引鍵。 使用 UseSetting 設定值時,此值會設定為字串,而不論其類型為何。

主機使用設定最後一個值的任何選項。 如需詳細資訊,請參閱下一節的覆寫組態

應用程式索引鍵 (名稱)

當主機建構期間呼叫 UseStartupConfigure 時,則會自動設定 IWebHostEnvironment.ApplicationName 屬性。 該值會設定為包含應用程式進入點的組件名稱。 若要明確設定值,請使用 WebHostDefaults.ApplicationKey

索引鍵:applicationName
類型string
預設:包含應用程式進入點的組件名稱。
設定使用UseSetting
環境變數ASPNETCORE_APPLICATIONNAME

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")

擷取啟動錯誤

此設定會控制啟動錯誤的擷取。

索引鍵:captureStartupErrors
類型bool (true1)
預設值:預設值為 false,除非應用程式在 IIS 後端使用 true 執行,其中預設值為 Kestrel。
設定使用CaptureStartupErrors
環境變數ASPNETCORE_CAPTURESTARTUPERRORS

當它為 false 時,啟動期間發生的錯誤會導致主機結束。 當它為 true 時,主機會擷取啟動期間的例外狀況,並嘗試啟動伺服器。

WebHost.CreateDefaultBuilder(args)
    .CaptureStartupErrors(true)

內容根目錄

此設定可決定 ASP.NET Core 開始搜尋內容檔案的位置。

索引鍵:contentRoot
類型string
預設值:預設為應用程式組件所在的資料夾。
設定使用UseContentRoot
環境變數ASPNETCORE_CONTENTROOT

內容根目錄也作為 Web 根目錄的基底路徑。 如果內容根路徑不存在,就無法啟動主機。

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

如需詳細資訊,請參閱

詳細錯誤

決定是否應該擷取詳細的錯誤。

索引鍵:detailedErrors
類型bool (true1)
預設值:false
設定使用UseSetting
環境變數ASPNETCORE_DETAILEDERRORS

啟用時 (或當 Environment 設定為 Development 時),應用程式會擷取詳細例外狀況。

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

環境

設定應用程式的環境。

索引鍵:environment
類型string
預設值:Production
設定使用UseEnvironment
環境變數ASPNETCORE_ENVIRONMENT

環境可以設定為任何值。 架構定義的值包括 DevelopmentStagingProduction。 值不區分大小寫。 根據預設,Environment 是從 ASPNETCORE_ENVIRONMENT 環境變數讀取。 使用 Visual Studio 時,可以在 launchSettings.json 檔案中設定環境變數。 如需詳細資訊,請參閱在 ASP.NET Core 中使用多個環境 (部分機器翻譯)。

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

裝載啟動組件

設定應用程式的裝載啟動組件。

索引鍵:hostingStartupAssemblies
類型string
預設值:空字串
設定使用UseSetting
環境變數ASPNETCORE_HOSTINGSTARTUPASSEMBLIES

在啟動時載入的裝載啟動組件字串,以分號分隔。

雖然設定值會預設為空字串,但裝載啟動組件一律會包含應用程式的組件。 提供裝載啟動組件時,它們會新增至應用程式的組件,以便在應用程式在啟動時建置其通用服務時載入。

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2")

HTTPS 連接埠

設定 HTTPS 重新導向連接埠。 用於強制 HTTPS

金鑰:https_port
類型string
預設值:未設定預設值。
設定使用UseSetting
環境變數ASPNETCORE_HTTPS_PORTS

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

裝載啟動排除組件

在啟動時排除以分號分隔的裝載啟動組件字串。

索引鍵:hostingStartupExcludeAssemblies
類型string
預設值:空字串
設定使用UseSetting
環境變數ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2")

偏好裝載 URL

表示主機是否應接聽使用 WebHostBuilder 設定的 URL,而不是 IServer 實作所設定的 URL。

索引鍵:preferHostingUrls
類型bool (true1)
預設值:false
設定使用PreferHostingUrls
環境變數ASPNETCORE_PREFERHOSTINGURLS

WebHost.CreateDefaultBuilder(args)
    .PreferHostingUrls(true)

防止裝載啟動

可防止自動載入裝載啟動組件,包括應用程式組件所設定的裝載啟動組件。 如需詳細資訊,請參閱在 ASP.NET Core 中使用裝載啟動組件 (部分機器翻譯)。

索引鍵preventHostingStartup
類型bool (true1)
預設值:false
設定使用UseSetting
環境變數ASPNETCORE_PREVENTHOSTINGSTARTUP

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

伺服器 URL

表示伺服器應該接聽要求的 IP 位址或主機位址,以及連接埠和通訊協定。

索引鍵:urls
類型string
預設值:http://localhost:5000
設定使用UseUrls
環境變數ASPNETCORE_URLS

設定為伺服器應該回應的 URL 前置清單,並以分號 (;) 分隔。 例如: http://localhost:123 。 使用 "*" 表示伺服器應接聽任何 IP 位址或主機名稱上的要求,並使用指定的連接埠和通訊協定 (例如,http://*:5000)。 通訊協定 (http://https://) 必須包含在每個 URL 中。 支援的格式會依伺服器而有所不同。

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

Kestrel 有它自己的端點設定 API。 如需詳細資訊,請參閱設定 ASP.NET Core Kestrel Web 伺服器的端點

關機逾時

指定等待 Web 主機關機的時間長度。

索引鍵:shutdownTimeoutSeconds
類型int
預設值:5
設定使用UseShutdownTimeout
環境變數ASPNETCORE_SHUTDOWNTIMEOUTSECONDS

雖然索引鍵接受 intUseSetting (例如 .UseSetting(WebHostDefaults.ShutdownTimeoutKey, "10")),UseShutdownTimeout 擴充方法會採用 TimeSpan

在逾時期間,裝載會:

如果在所有的託管服務停止之前逾時期限已到期,則應用程式關閉時,會停止任何剩餘的作用中服務。 即使服務尚未完成處理也會停止。 如果服務需要更多時間才能停止,請增加逾時。

WebHost.CreateDefaultBuilder(args)
    .UseShutdownTimeout(TimeSpan.FromSeconds(10))

啟動組件

決定要搜尋 Startup 類別的組件。

索引鍵:startupAssembly
類型string
預設值:應用程式的組件
設定使用UseStartup
環境變數ASPNETCORE_STARTUPASSEMBLY

可以參考依名稱 (string) 或類型 (TStartup) 的組件。 如果呼叫多個 UseStartup 方法,最後一個將會優先。

WebHost.CreateDefaultBuilder(args)
    .UseStartup("StartupAssemblyName")
WebHost.CreateDefaultBuilder(args)
    .UseStartup<TStartup>()

Web 根目錄

設定應用程式靜態資產的相對路徑。

索引鍵:webroot
類型string
預設值:預設值為 wwwroot{content root}/wwwroot 的路徑必須存在。 如果路徑不存在,則會使用無作業檔案提供者。
設定使用UseWebRoot
環境變數ASPNETCORE_WEBROOT

WebHost.CreateDefaultBuilder(args)
    .UseWebRoot("public")

如需詳細資訊,請參閱

覆寫組態

使用 Configuration 來設定 Web 主機。 在下列範例中,主機組態選擇性地指定於 hostsettings.json 檔案中。 從 hostsettings.json 檔案載入的任何設定,可以用命令列引數覆寫。 組建組態 (在 config 中) 用以使用 UseConfiguration 來設定主機。 IWebHostBuilder 設定會新增到應用程式的組態,但反之則不然 ConfigureAppConfiguration 並不會影響 IWebHostBuilder 組態。

首先使用 hostsettings.json 組態來覆寫 UseUrls 所提供的設定,其次是命令列引數:

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 複製到主機建立器的組態。 因此,為 JSON、INI 和 XML 設定檔設定 reloadOnChange: true 沒有任何作用。

若要指定主機在特定 URL 上執行,所要的值可以在執行 dotnet run 時從命令提示字元傳入。 命令列引數會覆寫 hostsettings.json 檔的 urls 值,且伺服器會接聽連接埠 8080:

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

管理主機

執行

Run 方法會啟動 Web 應用程式,並且封鎖呼叫執行緒,直到主機關閉為止:

host.Run();

啟動

藉由呼叫 Start 方法,以非封鎖方式執行主機:

using (host)
{
    host.Start();
    Console.ReadLine();
}

如果 URL 的清單傳遞至 Start 方法,它會接聽指定的 URL:

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 預設值,使用便利的靜態方法初始化並啟動新的主機。 這些方法會啟動伺服器而無主控台輸出,且在使用 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> routeBuilder)

使用 IRouteBuilder (Microsoft.AspNetCore.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 回應
http://localhost:5000/hello/Martin Hello, Martin!
http://localhost:5000/buenosdias/Catrina Buenos dias, Catrina!
http://localhost:5000/throw/ooops! 擲回例外狀況,字串為 "ooops!"
http://localhost:5000/throw 擲回例外狀況,字串為 "Un 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 和 IRouteBuilder 的執行個體:

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<IApplicationBuilder> app) 相同的結果,除了應用程式會在 http://localhost:8080 回應。

IWebHostEnvironment 介面

IWebHostEnvironment 介面提供應用程式的 Web 裝載環境相關資訊。 使用建構函式插入以取得 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
    }
}

以慣例為基礎的方法可用來根據環境在啟動時設定應用程式。 或者,將 IWebHostEnvironment 插入至 Startup 建構函式,以便用於 ConfigureServices

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 也提供 IsStagingIsProductionIsEnvironment(string environmentName) 方法。 如需詳細資訊,請參閱在 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;
}

建立自訂中介軟體時,IWebHostEnvironment 可以插入至 Invoke 方法:

public async Task Invoke(HttpContext context, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Configure middleware for Development
    }
    else
    {
        // Configure middleware for Staging/Production
    }

    var contentRootPath = env.ContentRootPath;
}

IHostApplicationLifetime 介面

IHostApplicationLifetime 允許啟動後和關機活動。 在介面上的三個屬性是用來註冊定義啟動和關閉事件之 Action 方法的取消語彙基元。

取消語彙基元 觸發時機…
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 會要求應用程式終止。 當呼叫類別的 Shutdown 方法時,下列類別使用 StopApplication 來順利關閉應用程式:

public class MyClass
{
    private readonly IHostApplicationLifetime _appLifetime;

    public MyClass(IHostApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public void Shutdown()
    {
        _appLifetime.StopApplication();
    }
}

範圍驗證

如果應用程式的環境為 [開發],則 CreateDefaultBuilder 會將 ServiceProviderOptions.ValidateScopes 設定為 true

ValidateScopes 設定為 true 時,預設服務提供者會執行檢查以確認:

  • 範圍服務不是直接或間接由根服務提供者解析。
  • 範圍服務不是直接或間接插入至單一服務。

根服務提供者會在呼叫 BuildServiceProvider 時建立。 當提供者啟動應用程式時,根服務提供者的存留期與應用程式/伺服器的存留期一致,並會在應用程式關閉時處置。

範圍服務會由建立這些服務的容器處置。 若是在根容器中建立範圍服務,因為當應用程式/伺服器關機時,服務只會由根容器處理,所以服務的存留期會提升為單一服務等級。 當呼叫 BuildServiceProvider 時,驗證服務範圍會攔截到這些情況。

若要一律驗證範圍,包括在生產環境中,請使用主機建立器上的 UseDefaultServiceProvider 來設定 ServiceProviderOptions

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

其他資源

ASP.NET Core 應用程式會設定並啟動「主機」。 主機負責應用程式啟動和存留期管理。 至少,主機會設定伺服器和要求處理管線。 主機也可以設定記錄、相依性插入和設定。

此文章涵蓋 Web 主機,而且我們僅因為回溯相容性而繼續提供它。 ASP.NET Core 範本會建立 .NET 泛型主機,建議用於所有類型的應用程式。

設定主機

使用 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>();
}

呼叫 CreateDefaultBuilder 的程式碼位於名為 CreateWebHostBuilder 的方法中,這將它與 Main 中呼叫產生器物件上之 Run 的方法分開。 若您使用e Entity Framework Core 工具,則此分開是必要的。 工具預期找到它們可以在設計階段呼叫的 CreateWebHostBuilder 方法,以在不執行應用程式的情況下設定主機。 替代方式是實作 IDesignTimeDbContextFactory。 如需詳細資訊,請參閱設計階段 DbContext 建立

CreateDefaultBuilder 會執行下列工作:

CreateDefaultBuilder 所定義的組態可以透過 ConfigureAppConfigurationConfigureLogging,以及 IWebHostBuilder 的其他方法和擴充方法加以覆寫及擴增。 數個範例如下:

  • ConfigureAppConfiguration 用於為應用程式指定額外的 IConfiguration。 下列 ConfigureAppConfiguration 呼叫會新增委派,以在 appsettings.xml 檔案中包含應用程式組態。 可能會多次呼叫 ConfigureAppConfiguration。 請注意,此組態不適用於主機 (例如,伺服器 URL 或環境)。 請參閱主機組態值一節。

    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
        })
        ...
    
  • 下列 ConfigureLogging 呼叫會新增委派,將最低的記錄層級 (SetMinimumLevel) 設定為 LogLevel.Warning。 此設定會覆寫 CreateDefaultBuilderappsettings.Development.json (LogLevel.Debug) 和 appsettings.Production.json (LogLevel.Error) 中所作的設定。 可能會多次呼叫 ConfigureLogging

    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging => 
        {
            logging.SetMinimumLevel(LogLevel.Warning);
        })
        ...
    
  • 下列 ConfigureKestrel 呼叫會覆寫當 CreateDefaultBuilder 設定 Kestrel 時建立的預設 Limits.MaxRequestBodySize 30,000,000 位元組:

    WebHost.CreateDefaultBuilder(args)
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.MaxRequestBodySize = 20000000;
        });
    

「內容根目錄」會決定主機搜尋內容檔案 (例如 MVC 檢視檔案) 的位置。 從專案的根資料夾啟動應用程式時,會使用專案的根資料夾作為內容根目錄。 這是 Visual Studiodotnet 新範本中使用的預設值。

如需應用程式設定的詳細資訊,請參閱 ASP.NET Core 中的組態

注意

作為使用靜態 CreateDefaultBuilder 方法的替代做法,ASP.NET Core 2.x 支援從 WebHostBuilder 建立主機的方法。

設定主機時,可以提供 ConfigureConfigureServices 方法。 如果指定 Startup 類別,它必須定義 Configure 方法。 如需詳細資訊,請參閱 ASP.NET Core 中的應用程式啟動。 多次呼叫 ConfigureServices 會彼此附加。 對 WebHostBuilder 多次呼叫 ConfigureUseStartup 則會取代先前的設定。

主機組態值

WebHostBuilder 依賴下列方法來設定主機組態值:

  • 主機建立器組態,其中包含 ASPNETCORE_{configurationKey} 格式的環境變數。 例如: ASPNETCORE_ENVIRONMENT
  • UseContentRootUseConfiguration 等擴充功能 (請參閱覆寫組態一節)。
  • UseSetting 和相關聯的索引鍵。 使用 UseSetting 設定值時,此值會設定為字串,而不論其類型為何。

主機使用設定最後一個值的任何選項。 如需詳細資訊,請參閱下一節的覆寫組態

應用程式索引鍵 (名稱)

當主機建構期間呼叫 UseStartupConfigure 時,則會自動設定 IWebHostEnvironment.ApplicationName 屬性。 該值會設定為包含應用程式進入點的組件名稱。 若要明確設定值,請使用 WebHostDefaults.ApplicationKey

索引鍵:applicationName
類型string
預設:包含應用程式進入點的組件名稱。
設定使用UseSetting
環境變數ASPNETCORE_APPLICATIONNAME

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")

擷取啟動錯誤

此設定會控制啟動錯誤的擷取。

索引鍵:captureStartupErrors
類型bool (true1)
預設值:預設值為 false,除非應用程式在 IIS 後端使用 true 執行,其中預設值為 Kestrel。
設定使用CaptureStartupErrors
環境變數ASPNETCORE_CAPTURESTARTUPERRORS

當它為 false 時,啟動期間發生的錯誤會導致主機結束。 當它為 true 時,主機會擷取啟動期間的例外狀況,並嘗試啟動伺服器。

WebHost.CreateDefaultBuilder(args)
    .CaptureStartupErrors(true)

內容根目錄

此設定可決定 ASP.NET Core 開始搜尋內容檔案的位置。

索引鍵:contentRoot
類型string
預設值:預設為應用程式組件所在的資料夾。
設定使用UseContentRoot
環境變數ASPNETCORE_CONTENTROOT

內容根目錄也作為 Web 根目錄的基底路徑。 如果內容根路徑不存在,就無法啟動主機。

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

如需詳細資訊,請參閱

詳細錯誤

決定是否應該擷取詳細的錯誤。

索引鍵:detailedErrors
類型bool (true1)
預設值:false
設定使用UseSetting
環境變數ASPNETCORE_DETAILEDERRORS

啟用時 (或當 Environment 設定為 Development 時),應用程式會擷取詳細例外狀況。

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

環境

設定應用程式的環境。

索引鍵:environment
類型string
預設值:Production
設定使用UseEnvironment
環境變數ASPNETCORE_ENVIRONMENT

環境可以設定為任何值。 架構定義的值包括 DevelopmentStagingProduction。 值不區分大小寫。 根據預設,Environment 是從 ASPNETCORE_ENVIRONMENT 環境變數讀取。 使用 Visual Studio 時,可以在 launchSettings.json 檔案中設定環境變數。 如需詳細資訊,請參閱在 ASP.NET Core 中使用多個環境 (部分機器翻譯)。

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

裝載啟動組件

設定應用程式的裝載啟動組件。

索引鍵:hostingStartupAssemblies
類型string
預設值:空字串
設定使用UseSetting
環境變數ASPNETCORE_HOSTINGSTARTUPASSEMBLIES

在啟動時載入的裝載啟動組件字串,以分號分隔。

雖然設定值會預設為空字串,但裝載啟動組件一律會包含應用程式的組件。 提供裝載啟動組件時,它們會新增至應用程式的組件,以便在應用程式在啟動時建置其通用服務時載入。

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2")

HTTPS 連接埠

設定 HTTPS 重新導向連接埠。 用於強制 HTTPS

金鑰:https_port
類型string
預設值:未設定預設值。
設定使用UseSetting
環境變數ASPNETCORE_HTTPS_PORTS

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

裝載啟動排除組件

在啟動時排除以分號分隔的裝載啟動組件字串。

索引鍵:hostingStartupExcludeAssemblies
類型string
預設值:空字串
設定使用UseSetting
環境變數ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2")

偏好裝載 URL

表示主機是否應接聽使用 WebHostBuilder 設定的 URL,而不是 IServer 實作所設定的 URL。

索引鍵:preferHostingUrls
類型bool (true1)
預設值:false
設定使用PreferHostingUrls
環境變數ASPNETCORE_PREFERHOSTINGURLS

WebHost.CreateDefaultBuilder(args)
    .PreferHostingUrls(true)

防止裝載啟動

可防止自動載入裝載啟動組件,包括應用程式組件所設定的裝載啟動組件。 如需詳細資訊,請參閱在 ASP.NET Core 中使用裝載啟動組件 (部分機器翻譯)。

索引鍵preventHostingStartup
類型bool (true1)
預設值:false
設定使用UseSetting
環境變數ASPNETCORE_PREVENTHOSTINGSTARTUP

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

伺服器 URL

表示伺服器應該接聽要求的 IP 位址或主機位址,以及連接埠和通訊協定。

索引鍵:urls
類型string
預設值:http://localhost:5000
設定使用UseUrls
環境變數ASPNETCORE_URLS

設定為伺服器應該回應的 URL 前置清單,並以分號 (;) 分隔。 例如: http://localhost:123 。 使用 "*" 表示伺服器應接聽任何 IP 位址或主機名稱上的要求,並使用指定的連接埠和通訊協定 (例如,http://*:5000)。 通訊協定 (http://https://) 必須包含在每個 URL 中。 支援的格式會依伺服器而有所不同。

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

Kestrel 有它自己的端點設定 API。 如需詳細資訊,請參閱 ASP.NET Core 中的 Kestrel Web 伺服器

關機逾時

指定等待 Web 主機關機的時間長度。

索引鍵:shutdownTimeoutSeconds
類型int
預設值:5
設定使用UseShutdownTimeout
環境變數ASPNETCORE_SHUTDOWNTIMEOUTSECONDS

雖然索引鍵接受 intUseSetting (例如 .UseSetting(WebHostDefaults.ShutdownTimeoutKey, "10")),UseShutdownTimeout 擴充方法會採用 TimeSpan

在逾時期間,裝載會:

如果在所有的託管服務停止之前逾時期限已到期,則應用程式關閉時,會停止任何剩餘的作用中服務。 即使服務尚未完成處理也會停止。 如果服務需要更多時間才能停止,請增加逾時。

WebHost.CreateDefaultBuilder(args)
    .UseShutdownTimeout(TimeSpan.FromSeconds(10))

啟動組件

決定要搜尋 Startup 類別的組件。

索引鍵:startupAssembly
類型string
預設值:應用程式的組件
設定使用UseStartup
環境變數ASPNETCORE_STARTUPASSEMBLY

可以參考依名稱 (string) 或類型 (TStartup) 的組件。 如果呼叫多個 UseStartup 方法,最後一個將會優先。

WebHost.CreateDefaultBuilder(args)
    .UseStartup("StartupAssemblyName")
WebHost.CreateDefaultBuilder(args)
    .UseStartup<TStartup>()

Web 根目錄

設定應用程式靜態資產的相對路徑。

索引鍵:webroot
類型string
預設值:預設值為 wwwroot{content root}/wwwroot 的路徑必須存在。 如果路徑不存在,則會使用無作業檔案提供者。
設定使用UseWebRoot
環境變數ASPNETCORE_WEBROOT

WebHost.CreateDefaultBuilder(args)
    .UseWebRoot("public")

如需詳細資訊,請參閱

覆寫組態

使用 Configuration 來設定 Web 主機。 在下列範例中,主機組態選擇性地指定於 hostsettings.json 檔案中。 從 hostsettings.json 檔案載入的任何設定,可以用命令列引數覆寫。 組建組態 (在 config 中) 用以使用 UseConfiguration 來設定主機。 IWebHostBuilder 設定會新增到應用程式的組態,但反之則不然 ConfigureAppConfiguration 並不會影響 IWebHostBuilder 組態。

首先使用 hostsettings.json 組態來覆寫 UseUrls 所提供的設定,其次是命令列引數:

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 複製到主機建立器的組態。 因此,為 JSON、INI 和 XML 設定檔設定 reloadOnChange: true 沒有任何作用。

若要指定主機在特定 URL 上執行,所要的值可以在執行 dotnet run 時從命令提示字元傳入。 命令列引數會覆寫 hostsettings.json 檔的 urls 值,且伺服器會接聽連接埠 8080:

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

管理主機

執行

Run 方法會啟動 Web 應用程式,並且封鎖呼叫執行緒,直到主機關閉為止:

host.Run();

啟動

藉由呼叫 Start 方法,以非封鎖方式執行主機:

using (host)
{
    host.Start();
    Console.ReadLine();
}

如果 URL 的清單傳遞至 Start 方法,它會接聽指定的 URL:

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 預設值,使用便利的靜態方法初始化並啟動新的主機。 這些方法會啟動伺服器而無主控台輸出,且在使用 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> routeBuilder)

使用 IRouteBuilder (Microsoft.AspNetCore.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 回應
http://localhost:5000/hello/Martin Hello, Martin!
http://localhost:5000/buenosdias/Catrina Buenos dias, Catrina!
http://localhost:5000/throw/ooops! 擲回例外狀況,字串為 "ooops!"
http://localhost:5000/throw 擲回例外狀況,字串為 "Un 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 和 IRouteBuilder 的執行個體:

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<IApplicationBuilder> app) 相同的結果,除了應用程式會在 http://localhost:8080 回應。

IWebHostEnvironment 介面

IWebHostEnvironment 介面提供應用程式的 Web 裝載環境相關資訊。 使用建構函式插入以取得 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
    }
}

以慣例為基礎的方法可用來根據環境在啟動時設定應用程式。 或者,將 IWebHostEnvironment 插入至 Startup 建構函式,以便用於 ConfigureServices

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 也提供 IsStagingIsProductionIsEnvironment(string environmentName) 方法。 如需詳細資訊,請參閱在 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;
}

建立自訂中介軟體時,IWebHostEnvironment 可以插入至 Invoke 方法:

public async Task Invoke(HttpContext context, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Configure middleware for Development
    }
    else
    {
        // Configure middleware for Staging/Production
    }

    var contentRootPath = env.ContentRootPath;
}

IHostApplicationLifetime 介面

IHostApplicationLifetime 允許啟動後和關機活動。 在介面上的三個屬性是用來註冊定義啟動和關閉事件之 Action 方法的取消語彙基元。

取消語彙基元 觸發時機…
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 會要求應用程式終止。 當呼叫類別的 Shutdown 方法時,下列類別使用 StopApplication 來順利關閉應用程式:

public class MyClass
{
    private readonly IHostApplicationLifetime _appLifetime;

    public MyClass(IHostApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public void Shutdown()
    {
        _appLifetime.StopApplication();
    }
}

範圍驗證

如果應用程式的環境為 [開發],則 CreateDefaultBuilder 會將 ServiceProviderOptions.ValidateScopes 設定為 true

ValidateScopes 設定為 true 時,預設服務提供者會執行檢查以確認:

  • 範圍服務不是直接或間接由根服務提供者解析。
  • 範圍服務不是直接或間接插入至單一服務。

根服務提供者會在呼叫 BuildServiceProvider 時建立。 當提供者啟動應用程式時,根服務提供者的存留期與應用程式/伺服器的存留期一致,並會在應用程式關閉時處置。

範圍服務會由建立這些服務的容器處置。 若是在根容器中建立範圍服務,因為當應用程式/伺服器關機時,服務只會由根容器處理,所以服務的存留期會提升為單一服務等級。 當呼叫 BuildServiceProvider 時,驗證服務範圍會攔截到這些情況。

若要一律驗證範圍,包括在生產環境中,請使用主機建立器上的 UseDefaultServiceProvider 來設定 ServiceProviderOptions

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

其他資源