理解ASP.NET Core 启动类(Startup) |
准备工作:一份ASP.NET Core Web API应用程序
当我们接触一份新框架时,第一件事就是找到程序入口,即Main方法
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
代码很简单,典型的建造者模式:通过 Startup类
默认的
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// 该方法由运行时调用,使用该方法向DI容器添加服务
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// 该方法由运行时调用,使用该方法配置HTTP请求管道
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
}
Startup构造函数当使用通用主机(Generic Host)时,Startup构造函数支持注入以下三种服务类型:
public Startup(
IConfiguration configuration,
IHostEnvironment hostEnvironment,
IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
HostEnvironment = hostEnvironment;
WebHostEnvironment = webHostEnvironment;
}
public IConfiguration Configuration { get; }
public IHostEnvironment HostEnvironment { get; set; }
public IWebHostEnvironment WebHostEnvironment { get; set; }
这里你会发现 ConfigureServices
常用的服务有(部分服务框架已默认注册):
Configure
常用的中间件有
省略Startup类另外,
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// ConfigureServices 可以调用多次,最终会将结果聚合
webBuilder.ConfigureServices(services =>
{
})
// Configure 如果调用多次,则只有最后一次生效
.Configure(app =>
{
var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
});
});
IStartupFilter
public interface IStartupFilter
{
Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next);
}
有时,我们想要将一系列相关中间件的注册封装到一起,那么我们只需要通过实现
我们可以通过一个例子来验证一下中间件的注册顺序 。 首先是三个
public class FirstStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
=> app =>
{
app.Use((context, next) =>
{
Console.WriteLine("First");
return next();
});
next(app);
};
}
public class SecondStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
=> app =>
{
app.Use((context, next) =>
{
Console.WriteLine("Second");
return next();
});
next(app);
};
}
public class ThirdStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
=> app =>
{
app.Use((context, next) =>
{
Console.WriteLine("Third");
return next();
});
next(app);
};
}
接下来进行注册:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// 第一个被注册
services.AddTransient<IStartupFilter, FirstStartupFilter>();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureServices(services =>
{
// 第三个被注册
services.AddTransient<IStartupFilter, ThirdStartupFilter>();
});
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 第二个被注册
services.AddTransient<IStartupFilter, SecondStartupFilter>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 第四个被注册
app.Use((context, next) =>
{
Console.WriteLine("Forth");
return next();
});
}
}
最后通过输出可以看到,执行顺序的确是这样子的 。
IHostingStartup与
下面我们就来看一下该如何使用它 。 HostingStartup 程序集要创建HostingStartup程序集,可以通过创建类库项目或无入口点的控制台应用来实现 。 接下来咱们还是看一下上面提到过的
using SkyApm.Agent.AspNetCore;
[assembly: HostingStartup(typeof(SkyApmHostingStartup))]
namespace SkyApm.Agent.AspNetCore
{
internal class SkyApmHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services => services.AddSkyAPM(ext => ext.AddAspNetCoreHosting()));
}
}
}
该HostingStartup类:
HostingStartup 特性
当程序启动时,会自动扫描入口程序集和配置的待激活的的程序集列表(参见下方:激活HostingStarup程序集),来找到所有的 以
using SkyApm.Agent.AspNetCore;
[assembly: HostingStartup(typeof(SkyApmHostingStartup))]
namespace SkyApm.Agent.AspNetCore
{
internal class SkyApmHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services => services.AddSkyAPM(ext => ext.AddAspNetCoreHosting()));
}
}
}
激活HostingStarup程序集要激活HostingStarup程序集,我们有两种配置方式: 1.使用环境变量(推荐)使用环境变量,无需侵入程序代码,所以我更推荐大家使用这种方式 。 配置环境变量 另外,还有一个环境变量,叫做 我们在 launchSettings.json 中添加两个程序集:
"environmentVariables": {
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SkyAPM.Agent.AspNetCore;HostingStartupLibrary"
}
2.在程序中配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseSetting(
WebHostDefaults.HostingStartupAssembliesKey,
"SkyAPM.Agent.AspNetCore;HostingStartupLibrary")
.UseStartup<Startup>();
});
这样就配置完成了,很🐮🍺的一个功能点吧! 需要注意的是,无论使用哪种配置方式,当存在多个HostingStartup程序集时,将按配置这些程序集时的书写顺序执行 多环境配置一款软件,一般要经过需求分析、设计编码,单元测试、集成测试以及系统测试等一系列测试流程,验收,最终上线 。那么,就至少需要4套环境来保证系统运行:
环境配置方式通过环境变量 注意:如果未指定环境,默认情况下,为 Production 在项目的Properties文件夹里面,有一个“launchSettings.json”文件,该文件是用于配置VS中项目启动的 。
Project:启动 Kestrel IISExpress:启动IIS Express IIS:不启用任何Web服务器,使用IIS
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
// 如果不指定profile,则默认选择第一个
// Development
"ASP.NET.WebAPI": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
// Test
"ASP.NET.WebAPI.Test": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Test"
}
},
// Staging
"ASP.NET.WebAPI.Staging": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Staging"
}
},
// Production
"ASP.NET.WebAPI.Production": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
},
// 用于测试在未指定环境时,默认是否为Production
"ASP.NET.WebAPI.Default": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000"
}
}
}
配置完成后,就可以在VS上方工具栏中的项目启动处选择启动项了 基于环境的 StartupStartup类支持针对不同环境进行个性化配置,有三种方式:
1.将
|