• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

理解ASP.NET Core 启动类(Startup)

asp 搞代码 4年前 (2022-01-03) 40次浏览 已收录 0个评论
文章目录[隐藏]

这篇文章主要介绍了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(); }); }

代码很简单,典型的建造者模式:通过IHostBuilder创建一个通用主机(Generic Host),然后启动它(至于什么是通用主机,咱们后续的文章会说到)。咱们不要一上来就去研究CreateDefaultBuilderConfigureWebHostDefaults这些方法的源代码,应该去寻找能看的见、摸得着的,很明显,只有Startup

Startup类

Startup类承担应用的启动任务,所以按照约定,起名为Startup,不过你可以修改为任意类名(强烈建议类名为Startup)。

默认的Startup结构很简单,包含:

  • 构造函数
  • Configuration属性
  • ConfigureServices方法
  • Configure方法
 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构造函数支持注入以下三种服务类型:

  • IConfigu来源gaodai$ma#com搞$$代**码网ration
  • IWebHostEnvironment
  • IHostEnvironment
 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; }

这里你会发现 HostEnvironmentWebHostEnvironment 的实例是同一个。别着急,后续文章我们聊到Host的时候,你就明白了。

ConfigureServices

  • 该方法是可选的
  • 该方法用于添加服务到DI容器中
  • 该方法在Configure方法之前被调用
  • 该方法要么无参数,要么只能有一个参数且类型必须为IServiceCollection
  • 该方法内的代码大多是形如Add{Service}的扩展方法

常用的服务有(部分服务框架已默认注册):

  • AddControllers:注册Controller相关服务,内部调用了AddMvcCoreAddApiExplorerAddAuthorizationAddCorsAddDataAnnotationsAddFormatterMappings等多个扩展方法
  • AddOptions:注册Options相关服务,如IOptionsIOptionsSnapshotIOptionsMonitorIOptionsFactoryIOptionsMonitorCache等。很多服务都需要Options,所以很多服务注册的扩展方法会在内部调用AddOptions
  • AddRouting:注册路由相关服务,如IInlineConstraintResolverLinkGeneratorIConfigureOptionsRoutePatternTransformer
  • AddAddLogging:注册Logging相关服务,如ILoggerFactoryILoggerIConfigureOptions>
  • AddAuthentication:注册身份认证相关服务,以方便后续注册JwtBearer、Cookie等服务
  • AddAuthorization:注册用户授权相关服务
  • AddMvc:注册Mvc相关服务,比如Controllers、Views、RazorPages等
  • AddHealthChecks:注册健康检查相关服务,如HealthCheckServiceIHostedService

Configure

  • 该方法是必须的
  • 该方法用于配置HTTP请求管道,通过向管道添加中间件,应用不同的响应方式。
  • 该方法在ConfigureServices方法之后被调用
  • 该方法中的参数可以接受任何已注入到DI容器中的服务
  • 该方法内的代码大多是形如Use{Middleware}的扩展方法
  • 该方法内中间件的注册顺序与代码的书写顺序是一致的,先注册的先执行,后注册的后执行

常用的中间件有

  • UseDeveloperExceptionPage:当发生异常时,展示开发人员异常信息页。如图

  • UseRouting:路由中间件,根据Url中的路径导航到对应的Endpoint。必须与UseEndpoints搭配使用。
  • UseEndpoints:执行路由所选择的Endpoint对应的委托。
  • UseAuthentication:身份认证中间件,用于对请求用户的身份进行认证。比如,早晨上班打卡时,管理员认出你是公司员工,那么才允许你进入公司。
  • UseAuthorization:用户授权中间件,用于对请求用户进行授权。比如,虽然你是公司员工,但是你是一名.NET开发工程师,那么你只允许坐在.NET开发工程师区域的工位上,而不能坐在老总的办公室里。
  • UseMvc:Mvc中间件。
  • UseHealthChecks:健康检查中间件。
  • UseMiddleware:用来添加匿名中间件的,通过该方法,可以方便的添加自定义中间件。

省略Startup类

另外,Startup类也可以省略,直接进行如下配置即可(虽然可以这样做,但是不推荐):

 public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { // ConfigureServices 可以调用多次,最终会将结果聚合 webBuilder.ConfigureServices(services => { }) // Configure 如果调用多次,则只有最后一次生效 .Configure(app => { var env = app.ApplicationServices.GetRequiredService(); }); });

IStartupFilter

 public interface IStartupFilter { Action Configure(Action next); }

有时,我们想要将一系列相关中间件的注册封装到一起,那么我们只需要通过实现IStartupFilter,并在Startup.ConfigureServices中配置IStartupFilter的依赖注入即可。

  • IStartupFilter中配置的中间件,总是比Startup类中Configure方法中的中间件先注册;对于多个IStartupFilter实现,执行顺序与服务注册时的顺序一致

我们可以通过一个例子来验证一下中间件的注册顺序。

首先是三个IStartupFilter的实现类:

 public class FirstStartupFilter : IStartupFilter { public Action Configure(Action next) => app => { app.Use((context, next) => { Console.WriteLine("First"); return next(); }); next(app); }; } public class SecondStartupFilter : IStartupFilter { public Action Configure(Action next) => app => { app.Use((context, next) => { Console.WriteLine("Second"); return next(); }); next(app); }; } public class ThirdStartupFilter : IStartupFilter { public Action Configure(Action 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(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }) .ConfigureServices(services => { // 第三个被注册 services.AddTransient(); }); public class Startup { public void ConfigureServices(IServiceCollection services) { // 第二个被注册 services.AddTransient(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 第四个被注册 app.Use((context, next) => { Console.WriteLine("Forth"); return next(); }); } }

最后通过输出可以看到,执行顺序的确是这样子的。

First
Second
Third
Forth

IHostingStartup

IStartupFilter不同的是,IHostingStartup可以在启动时通过外部程序集向应用增加更多功能。不过这要求必须调用ConfigureWebHostConfigureWebHostDefaults等类似用来配置Web主机的扩展方法

我们经常使用的Nuget包SkyApm.Agent.AspNetCore就使用了该特性。

下面我们就来看一下该如何使用它。

HostingStartup 程序集

要创建HostingStartup程序集,可以通过创建类库项目或无入口点的控制台应用来实现。

接下来咱们还是看一下上面提到过的SkyApm.Agent.AspNetCore

 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类:

  • 实现了IHostingStartup接口
  • Configure方法中使用IWebHostBuilder来添加增强功能
  • 配置了HostingStartup特性

HostingStartup 特性

HostingStartup特性用于标识哪个类是HostingStartup类,HostingStartup类需要实现IHostingStartup接口。

当程序启动时,会自动扫描入口程序集和配置的待激活的的程序集列表(参见下方:激活HostingStarup程序集),来找到所有的HostingStartup特性,并通过反射的方式创建Startup并调用Configure方法。

SkyApm.Agent.AspNetCore为例

 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.使用环境变量(推荐)

使用环境变量,无需侵入程序代码,所以我更推荐大家使用这种方式。

配置环境变量ASPNETCORE_HOSTINGSTARTUPASSEMBLIES,多个程序集使用分号(;)进行分隔,用于添加要激活的程序集。变量WebHostDefaults.HostingStartupAssembliesKey就是指代这个环境变量的Key。

另外,还有一个环境变量,叫做ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES,多个程序集使用分号(;)进行分隔,用于排除要激活的程序集。变量WebHostDefaults.HostingStartupExcludeAssembliesKey就是指代这个环境变量的Key。

我们在 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(); });

这样就配置完成了,很

以上就是理解ASP.NET Core 启动类(Startup)的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:理解ASP.NET Core 启动类(Startup)

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址