ASP.NET Core 應(yīng)用使用 Startup 類,按照約定命名為 Startup。 Startup 類:
當(dāng)應(yīng)用啟動時,運行時調(diào)用 ConfigureServices 和 Configure:
C#
public class Startup
{
// Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
...
}
// Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
...
}
}
在構(gòu)建應(yīng)用的主機時,系統(tǒng)為應(yīng)用指定 Startup 類。 在 Program 類的主機生成器上調(diào)用 Build時,將生成應(yīng)用的主機。 通常通過在主機生成器上調(diào)用 WebHostBuilderExtensions.UseStartup<TStartup> 方法來指定 Startup 類:
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>();
}
主機提供 Startup 類構(gòu)造函數(shù)可用的某些服務(wù)。 應(yīng)用通過 ConfigureServices 添加其他服務(wù)。 然后,主機和應(yīng)用服務(wù)都可以在 Configure 和整個應(yīng)用中使用。
在 Startup 類中注入依賴關(guān)系的常見用途為注入:
C#
public class Startup
{
private readonly IHostingEnvironment _env;
private readonly IConfiguration _config;
private readonly ILoggerFactory _loggerFactory;
public Startup(IHostingEnvironment env, IConfiguration config,
ILoggerFactory loggerFactory)
{
_env = env;
_config = config;
_loggerFactory = loggerFactory;
}
public void ConfigureServices(IServiceCollection services)
{
var logger = _loggerFactory.CreateLogger<Startup>();
if (_env.IsDevelopment())
{
// Development service configuration
logger.LogInformation("Development environment");
}
else
{
// Non-development service configuration
logger.LogInformation($"Environment: {_env.EnvironmentName}");
}
// Configuration is available during startup.
// Examples:
// _config["key"]
// _config["subsection:suboption1"]
}
}
注入 IHostingEnvironment 的替代方法是使用基于約定的方法。 應(yīng)用為不同的環(huán)境(例如,StartupDevelopment)單獨定義 Startup 類時,相應(yīng)的 Startup 類會在運行時被選中。 優(yōu)先考慮名稱后綴與當(dāng)前環(huán)境相匹配的類。 如果應(yīng)用在開發(fā)環(huán)境中運行并包含 Startup 類和 StartupDevelopment 類,則使用 StartupDevelopment 類。 有關(guān)詳細(xì)信息,請參閱使用多個環(huán)境。
要詳細(xì)了解有關(guān)主機的詳細(xì)信息,請參閱主機。 有關(guān)在啟動過程中處理錯誤的信息,請參閱啟動異常處理。
典型模式是調(diào)用所有 Add{Service} 方法,然后調(diào)用所有 services.Configure{Service} 方法。 有關(guān)示例,請參閱配置標(biāo)識服務(wù)。
主機可能會在調(diào)用 Startup 方法之前配置某些服務(wù)。 有關(guān)詳細(xì)信息,請參閱主機。
對于需要大量設(shè)置的功能,IServiceCollection 上有 Add{Service} 擴展方法。 典型 ASP.NET Core 應(yīng)用將為實體框架、標(biāo)識和 MVC 注冊服務(wù):
C#
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}
將服務(wù)添加到服務(wù)容器,使其在應(yīng)用和 Configure 方法中可用。 服務(wù)通過依賴關(guān)系注入或 ApplicationServices 進行解析。
Configure 方法用于指定應(yīng)用響應(yīng) HTTP 請求的方式。 可通過將中間件組件添加到 IApplicationBuilder 實例來配置請求管道。 Configure 方法可使用 IApplicationBuilder,但未在服務(wù)容器中注冊。 托管創(chuàng)建 IApplicationBuilder 并將其直接傳遞到 Configure。
ASP.NET Core 模板配置的管道支持:
C#
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
每個 Use 擴展方法將一個或多個中間件組件添加到請求管道。 例如,UseMvc 擴展方法將路由中間件添加到請求管道,并將 MVC 配置為默認(rèn)處理程序。
請求管道中的每個中間件組件負(fù)責(zé)調(diào)用管道中的下一個組件,或在適當(dāng)情況下使鏈發(fā)生短路。 如果中間件鏈中未發(fā)生短路,則每個中間件都有第二次機會在將請求發(fā)送到客戶端前處理該請求。
其他服務(wù)(如 IHostingEnvironment 和 ILoggerFactory),也可以在 Configure 方法簽名中指定。如果指定,其他服務(wù)如果可用,將被注入。
有關(guān)如何使用 IApplicationBuilder 和中間件處理順序的詳細(xì)信息,請參閱 ASP.NET Core 中間件。
若要配置服務(wù)和請求處理管道,而不使用 Startup 類,請在主機生成器上調(diào)用 ConfigureServices和 Configure 便捷方法。 多次調(diào)用 ConfigureServices 將追加到另一個。 如果存在多個 Configure 方法調(diào)用,則使用最后一個 Configure 調(diào)用。
C#
public class Program
{
public static IHostingEnvironment HostingEnvironment { get; set; }
public static IConfiguration Configuration { get; set; }
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
})
.ConfigureServices(services =>
{
...
})
.Configure(app =>
{
var loggerFactory = app.ApplicationServices
.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<Program>();
var env = app.ApplicationServices.GetRequiredServices<IHostingEnvironment>();
var config = app.ApplicationServices.GetRequiredServices<IConfiguration>();
logger.LogInformation("Logged in Configure");
if (env.IsDevelopment())
{
...
}
else
{
...
}
var configValue = config["subsection:suboption1"];
...
});
}
在應(yīng)用的 Configure 中間件管道的開頭或末尾使用 IStartupFilter 來配置中間件。 IStartupFilter 有助于確保中間件在應(yīng)用請求處理管道的開始或結(jié)束時由庫添加的中間件之前或之后運行。
IStartupFilter 實現(xiàn)單個方法(即 Configure),該方法接收并返回 Action<IApplicationBuilder>。IApplicationBuilder 定義用于配置應(yīng)用請求管道的類。 有關(guān)詳細(xì)信息,請參閱使用 IApplicationBuilder 創(chuàng)建中間件管道。
在請求管道中,每個 IStartupFilter 實現(xiàn)一個或多個中間件。 篩選器按照添加到服務(wù)容器的順序調(diào)用。 篩選器可在將控件傳遞給下一個篩選器之前或之后添加中間件,從而附加到應(yīng)用管道的開頭或末尾。
下面的示例演示如何使用 IStartupFilter 注冊中間件。
RequestSetOptionsMiddleware 中間件從查詢字符串參數(shù)中設(shè)置選項值:
C#
public class RequestSetOptionsMiddleware
{
private readonly RequestDelegate _next;
private IOptions<AppOptions> _injectedOptions;
public RequestSetOptionsMiddleware(
RequestDelegate next, IOptions<AppOptions> injectedOptions)
{
_next = next;
_injectedOptions = injectedOptions;
}
public async Task Invoke(HttpContext httpContext)
{
Console.WriteLine("RequestSetOptionsMiddleware.Invoke");
var option = httpContext.Request.Query["option"];
if (!string.IsNullOrWhiteSpace(option))
{
_injectedOptions.Value.Option = WebUtility.HtmlEncode(option);
}
await _next(httpContext);
}
}
在 RequestSetOptionsStartupFilter 類中配置 RequestSetOptionsMiddleware:
C#
public class RequestSetOptionsStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestSetOptionsMiddleware>();
next(builder);
};
}
}
IStartupFilter 在 ConfigureServices 的服務(wù)容器中注冊,參數(shù) Startup 從 Startup 類外部注冊:
C#
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddTransient<IStartupFilter,
RequestSetOptionsStartupFilter>();
})
.UseStartup<Startup>()
.Build();
當(dāng)提供 option 的查詢字符串參數(shù)時,中間件在 MVC 中間件呈現(xiàn)響應(yīng)之前處理分配值:
中間件執(zhí)行順序由 IStartupFilter 注冊順序設(shè)置:
通過 IHostingStartup 實現(xiàn),可在啟動時從應(yīng)用 Startup 類之外的外部程序集向應(yīng)用添加增強功能。有關(guān)更多信息,請參見在 ASP.NET Core 中使用承載啟動程序集。
更多建議: