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

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

IStartupFilter

public interface IStartupFilter { Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next); }

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

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

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

首先是三个IStartupFilter的实现类:

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

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

First
Second
Third
Forth

IHostingStartup

与IStartupFilter不同的是,IHostingStartup可以在启动时通过外部程序集向应用增加更多功能。不过这要求必须调用ConfigureWebHost、ConfigureWebHostDefaults等类似用来配置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接口。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zysfdj.html