ASP.NET Core - IStartupFilter 与 IHostingStartup
ASP.NET Core - IStartupFilter 与 IHostingStartup
- 1. IStartupFilter
- 2 IHostingStartup
- 2.5.1 创建外部程序集
- 2.5.2 激活外部程序集
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.UseRoutingapp.UseAuthorizationapp.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 - .NET 6 的入口文件
相关文章:

ASP.NET Core - IStartupFilter 与 IHostingStartup
ASP.NET Core - IStartupFilter 与 IHostingStartup 1. IStartupFilter2 IHostingStartup2.5.1 创建外部程序集2.5.2 激活外部程序集 1. IStartupFilter 上面讲到的方式虽然能够根据不同环境将Startup中的启动逻辑进行分离,但是有些时候我们还会可以根据应用中的功能…...

【零基础租赁实惠GPU推荐及大语言模型部署教程01】
租赁GPU推荐及大语言模型部署简易教程 1 官网地址2 注册账号及登录3 租用GPU3.1 充值(不限制充值最低金额,1元亦可)3.2 容器实例(实际就是你租用的GPU电脑)3.3 选择镜像(选择基础环境:框架版本和…...
接口传参 data格式和json格式区别是什么
接口传参 data格式和json格式区别是什么 以下是接口传参 data 格式和 JSON 格式的区别: 定义和范围 Data 格式: 是一个较为宽泛的概念,它可以指代接口传递参数时所使用的任何数据的组织形式。包括但不限于 JSON、XML、Form 数据、纯文本、二进…...
踏上 C++ 编程之旅:开篇之作
踏上 C 编程之旅:开篇之作 在计算机编程的广袤天地中,C 宛如一座巍峨的高峰,吸引着无数开发者攀登探索。今天,就让我们一同开启这段充满挑战与惊喜的 C 编程之旅,在代码的世界里开辟属于自己的道路。 一、为什么选择…...

docker在不删除容器的情况下修改端口映射
注意:必须先停止docker服务!!!! 1) 停止容器 2) 停止docker服务(systemctl stop docker) 3) 修改这个容器的hostconfig.json和config.v2.json文件中的端口 先查看容器id docker inspect jenkins 进入该目录 hostcon…...
Mysql tinyint与Java的数据类型的对应关系
参考资料 理解误区——mysql中tinyint与Java的数据类型的对应关系;tinyint(1) 与tinyint(4)的区别 1.1 tinyint字段取值 数据库字段类型为 tinyint,值为0或1,直接通过SQL语句查询的话,0会取出false;1会取出true目前就想取出的结果为 0 或 1 selectpg_id ,pg_name…...

mac intel芯片下载安卓模拟器
一、调研 目前主流两个模拟器: 雷神模拟器 不支持macosmumu模拟器pro版 不支持macos intel芯片 搜索到mumu的Q&A中有 “Intel芯片Mac如何安装MuMu?” q&a🔗:https://mumu.163.com/mac/faq/install-on-intel-mac.html 提…...

掌握 Ubuntu 终端 mv 与 rename 命令的高效重命名使用方法
在日常的计算任务中,文件重命名是一个经常性的需求。对于熟悉图形用户界面(GUI)的人来说,通过右键点击并选择“重命名”选项,这个过程简单直接。然而,当涉及到大量文件或需要自动化流程时,命令行…...

【Python】数据容器:列表,元组,字符串,集合字典及通用操作
文章目录 一.序列1.1list列表定义常用操作列表的遍历 1.2tuple元组定义常见操作元组的遍历 1.3str字符串定义常见操作字符串的遍历 1.4序列常用操作——切片 二.set集合定义常见操作集合的遍历 三.dict字典定义常用操作字典的嵌套 *数据容器对比总结四.数据容器的通用操作4.1通…...

基于Oracle与PyQt6的电子病历多模态大模型图形化查询系统编程构建
一、引言 1.1 研究背景阐述 在当今数字化时代,医疗行业正经历着深刻的变革,数字化转型的需求日益迫切。电子病历(EMR)作为医疗信息化的核心,其管理的高效性和数据利用的深度对于提升医疗服务质量、优化临床决策以及推动医学研究具有至关重要的意义。传统的电子病历管理系…...

2025智能网联汽车数据分类分级白皮书
智能网联汽车作为现代交通技术的重要成果,其核心特征之一是产生了大量的、多样化的数据,这些数据不仅对提升车辆性能和用户体验至关重要,对维护交通安全、推动智能交通系统的发展具有深远影响。在数字经济时代,数据的价值日益凸显…...

使用Dify创建个问卷调查的工作流
为啥要使用Dify创建工作流呢?一个基于流程的智能体的实现,特别是基于业务的实现,使用Dify去实现时,通常都是一个对话工作流,当设计到相对复杂一些的流程时,如果将所有逻辑都放在对话工作流中去实现…...

紫光无人机AI飞控平台介绍
随着无人机技术的迅猛发展,无人机飞控平台的智能化需求不断提升。紫光无人机AI飞控平台作为一款创新型产品,为用户提供了从飞行控制到任务管理的一站式解决方案,尤其在AI实时识别和事件分析方面具有显著优势。本文将介绍平台的核心功能、技术…...

UI自动化测试:异常截图和page_source
自动化测试过程中,是否遇到过脚本执行中途出错却不知道原因的情况?测试人员面临的不仅是问题的复现,还有对错误的快速定位和分析。而异常截图与页面源码(Page Source)的结合,正是解决这一难题的利器。 在实…...

47,【5】BUUCTF web lovesql
进入靶场 可知是单引号闭合,属于字符串型注入 则后续方法与字符串型无异 使用order by 判断出字节数为3 使用union select寻找注入点时切记第一个select为空 库名geek 表名group_concat(table_name) from information_schema.tables where table_schemageek# geek…...

网络安全——常用语及linux系统
一、网络安全概念及法规 网络安全:网络空间安全 cyber security 信息系统:由计算机硬件、网络和通信设备、计算机软件、信息资源、信息用户和规章制度组成的已处理信息流为目的的人机一体化系统 信息系统安全三要素(CIA) 保密…...
json().get() 和 json[““] 的区别
以下是 json().get() 和 json[“”] 的区别: 使用方法和语法 json[“”]: 这是使用字典的索引操作符 [] 来访问 JSON 数据。假设 json 是一个字典,你可以通过 json[“key”] 的方式来获取对应 key 的值。 示例: python import js…...
深入解析CSS属性值计算:从声明到渲染的完整流程
目录 引言1. 确定声明值2. 层叠冲突3. 使用继承4. 使用默认值总结 引言 在网页开发中,理解CSS属性值的计算过程对于开发者来说至关重要。它不仅影响页面样式的最终呈现,还涉及到浏览器如何解析和应用样式规则。本文将深入探讨从无属性值到每个属性都有…...

npm发布工具包+使用
1.初始化package包 npm init -y {"name": "common-cjs-tools","version": "1.0.0","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" &&…...

28:CAN总线入门一:CAN的基本介绍
CAN总线入门 1、CAN总线简介和硬件电路1.1、CAN简要介绍1.2、硬件电路1.3、CAN总线的电平标准 2、帧格式2.1、数据帧(掌握)2.2、遥控帧(掌握)2.3、错误帧(了解)2.4、过载帧(了解)2.5…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...