1. IStartupFilter

  上面讲到的方式虽然能够根据不同环境将Startup中的启动逻辑进行分离,但是有些时候我们还会可以根据应用中的功能点将将一系列相关中间件的注册封装到一起,从 Startup 类中分离,单独进行维护,以便更清晰地管理我们的代码。

  这时候我们可以实现 IStartupFilter 接口,然后将其注入到容器之中,在应用启动的时候 IStartupFilter 实现类会被执行,从而完成对中间件的配置。

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

  通过源码可以看到,ASP.NET Core 框架在创建应用的时候,会从容器中提取出所有的 IStartupFilter 的实现类,循环执行,然后再执行 Startup 类中的 Configure 方法。

下面是一个测试例子 :

点击查看代码
public class FirstStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
Console.WriteLine("FirstStartupFilter");
return app => next(app);
}
} public class SecondStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
Console.WriteLine("SecondStartupFilter");
return app => next(app);
}
} 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.
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("Startup: ConfigureServices");
services.AddTransient<IStartupFilter, FirstStartupFilter>();
services.AddTransient<IStartupFilter, SecondStartupFilter>();
services.AddControllers();
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
Console.WriteLine("Startup.Configure");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting
app.UseAuthorization
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}

执行结果如下:

2 IHostingStartup

  第一次接触 IHostingStartup 的应用是在 Skywalking 的使用之中,当初觉得 Skywalking 仅仅通过配置一个环境变量就能集成相关的功能非常神奇,并不知道具体是怎么实现的。后面出于这点好奇心,了解了一下相关的原理,才知道原来是使用了 IHostingStartup 在启动时通过外部程序集向应用增加更多功能,它是 ASP.NETCore 框架原生提供的一种进行模块化开发的方式,使用它必须通过 Web 主机调用 ConfigureWebHost、ConfigureWebHostDefaults

配置方法。

通过源码可以看到,在调用 Build 方法构建主机的时候会获取外部程序集名称,然后将其加载,再通过HostingStartupAttribute 程序集特性找到配置的 HostingStartType,该类需要实现 IHostingStartup 解析,之后反射生成实例,调用其中的 Configure 方法,传入的时候 IWebHostBuider 对象,因此在 IHostingStartup 实现类中一样可以进行依赖注入、管道配置。

再看怎么获取外部程序集名称的:

可以看到是从配置系统中获取的,而 key 是 WebHostDefaults.HostingStartupAssembliesKey 常量,也就是 hostingStartupAssemblies,由于这里是 主机配置,所以我们可以通过 ASPNETCORE_HOSTINGSTARTUPASSEMBLIES 进行设置,Web 主机在加载环境变量的时候会截去前缀 ASPNETCORE_ ,配置系统中 key 不区分大小写。

下面看看如何使用 IHostingStartup:

2.5.1 创建外部程序集

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



之后创建一个 IHostingStartup 接口的实现类

[assembly: HostingStartup(typeof(MyHostingStartup))]
namespace HostingStartupLib
{
public class MyHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices(services => { })
.ConfigureAppConfiguration(app => { });
Console.WriteLine("Init External Amsebly!");
}
}
}

该类的 Configure 方法中入参为 IWebHostBuilder ,通过 IWebHostBuilder 来添加增强功能,像 Program.cs 文件中对主机进行配置一样。

之后,需要配置 HostingStartup 特性,这是一个程序集特性,指定当前程序集的 IHostingStartup 实现类类型。

2.5.2 激活外部程序集

有了一个这样的 HostingStartup 外部程序集之后,我们在主体应用项目中可以这样进行激活。

首先,将该程序集应用进项目之中

然后,向配置系统中设置外部程序集的名称,以实现在构建主机的时候进行加载,由于是主机配置,所以我们可以通过几种方式进行设置:

(1) 在构建主机的时候进行配置

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseSetting(
WebHostDefaults.HostingStartupAssembliesKey,
"HostingStartupLib")
.UseStartup<Startup>();
});

其实这里的 UseSetting 方法就是就是往配置系统中添加配置而已

(2) 通过环境变量进行设置

Web主机在启动的时候会通过环境变量提供程序获取环境变量作为主机配置,并且会在写入配置系统的时候会截取掉 ASPNET_ 前缀,我们在配置的时候要用 ASPNETCORE_HOSTINGSTARTUPASSEMBLIES 作为 key。这种无需侵入程序代码,是更为推荐的方式。

我们可以直接在机器的环境变量列表中配置,但是如果只是开发环境的话也可以通过 launchSettings.json 。

无论是那种配置方式,如果需要同时可以用英文逗号 ; 分隔。除了 ASPNETCORE_HOSTINGSTARTUPASSEMBLIES 环境变量之外,和外部程序集有关的配置还有 ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES,用于排除要激活的程序集,ASPNETCORE_PREVENTHOSTINGSTARTUP,用于配置是否禁止外部程序集。

参考文章:

官方文档-托管启动程序集

理解ASP.NET Core - Startup

ASP.NET Core 系列总结:

目录:ASP.NET Core 系列总结

上一篇:ASP.NET Core—入口文件

ASP.NET Core - IStartupFilter 与 IHostingStartup的更多相关文章

  1. ASP.NET Core 的 `Core` 有几种写法?

    一.概述 本文将会根据情况持续更新. 作为一个 Framework,ASP.NET Core 提供了诸多的扩展点.使用内置的组件和默认的配置通常就能够满足部分需求,当需要扩展的时就需要先去找出这些扩展 ...

  2. 探索ASP.NET Core中的IStartupFilter

    原文:Exploring IStartupFilter in ASP.NET Core 作者:Andrew Lock 译者:Lamond Lu 在本篇博客中,我将介绍一下IStartupFilter, ...

  3. ASP.NET Core 运行原理解剖[1]:Hosting

    ASP.NET Core 是新一代的 ASP.NET,第一次出现时代号为 ASP.NET vNext,后来命名为ASP.NET 5,随着它的完善与成熟,最终命名为 ASP.NET Core,表明它不是 ...

  4. ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍

    在上一章中,我们介绍了 ASP.NET Core 的启动过程,主要是对 WebHost 源码的探索.而本文则是对上文的一个补充,更加偏向于实战,详细的介绍一下我们在实际开发中需要对 Hosting 做 ...

  5. 【ASP.NET Core】运行原理之启动WebHost

    ASP.NET Core运行原理之启动WebHost 本节将分析WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build ...

  6. 使用 NLog 给 Asp.Net Core 做请求监控

    为了减少由于单个请求挂掉而拖垮整站的情况发生,给所有请求做统计是一个不错的解决方法,通过观察哪些请求的耗时比较长,我们就可以找到对应的接口.代码.数据表,做有针对性的优化可以提高效率.在 asp.ne ...

  7. 【ASP.NET Core】运行原理(1):创建WebHost

    本系列将分析ASP.NET Core运行原理 [ASP.NET Core]运行原理[1]:创建WebHost [ASP.NET Core]运行原理[2]:启动WebHost [ASP.NET Core ...

  8. Asp.net Core 启动流程分析

    新建的.net core 程序启动本质上是一个控制台应用程序,所以它的入口在Main方法中,所以启动的开始时从Main方法开始. public class Program { public stati ...

  9. ASP.NET Core管道详解[6]: ASP.NET Core应用是如何启动的?[下篇]

    要承载一个ASP.NET Core应用,只需要将GenericWebHostService服务注册到承载系统中即可.但GenericWebHostService服务具有针对其他一系列服务的依赖,所以在 ...

  10. 理解ASP.NET Core - [01] Startup

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 准备工作:一份ASP.NET Core Web API应用程序 当我们来到一个陌生的环境,第一 ...

随机推荐

  1. Websocket集群解决方案

    最近在项目中在做一个消息推送的功能,比如客户下单之后通知给给对应的客户发送系统通知,这种消息推送需要使用到全双工的websocket推送消息. 所谓的全双工表示客户端和服务端都能向对方发送消息.不使用 ...

  2. 第一百零七篇:基本数据类型(undefined,null,boolean类型)

    好家伙, 本篇内容为<JS高级程序设计>第三章学习笔记 1.数据类型 ECMAScript有6种简单数据类型(称为原始类型): Undefined, Null, Boolean, Numb ...

  3. Git 分支管理策略汇总

    原文链接: Git 分支管理策略 最近,团队新入职了一些小伙伴,在开发过程中,他们问我 Git 分支是如何管理的,以及应该怎么提交代码? 我大概说了一些规则,但仔细想来,好像也并没有形成一个清晰规范的 ...

  4. 嵌入式-C语言基础:实现字符串拷贝函数

    自己实现一个字符串的拷贝函数 #include<stdio.h> #include<stdlib.h> #include <string.h> char * mys ...

  5. 关于Go你不得不知道的小技巧

    目录 Go 箴言 Go 之禅 代码 使用 go fmt 格式化 多个 if 语句可以折叠成 switch 用 chan struct{} 来传递信号, chan bool 表达的不够清楚 30 * t ...

  6. .NET性能优化-使用内存+磁盘混合缓存

    我们回顾一下上一篇文章中的内容,有一个朋友问我这样一个问题: 我的业务依赖一些数据,因为数据库访问慢,我把它放在Redis里面,不过还是太慢了,有什么其它的方案吗? 其实这个问题比较简单的是吧?Red ...

  7. React Server Component: 混合式渲染

    作者:谢奇璇 React 官方对 Server Comopnent 是这样介绍的: zero-bundle-size React Server Components. 这是一种实验性探索,但相信该探索 ...

  8. day 26 form表单标签 & CSS样式表-选择器 & 样式:背景、字体、定位等

    html常用标签 嵌套页面 <!-- 嵌套页面 --> <div> <!-- target属性值可以通过指定的iframe的name属性值, 实现超链接页面,在嵌套页面展 ...

  9. 批量删除多个相同格式内容的Excel表格的列

    Sub Del_Col()Application.DisplayAlerts = FalseDim myFiles As StringDim myExcels As StringWith Applic ...

  10. go操作Kfaka

    目录 1. Kafka介绍 1.1.1. Kafka是什么 1.1.2. Kafka的特点 1.1.3. 常用的场景 1.1.4. Kafka中包含以下基础概念 1.1.5. 消息 1.1.6. 消息 ...