.NET 8 IApplicationBuilder详解
在上节中我们已经得知 WebApplication 实现了 IApplicationBuilder,我们浅谈了其pipe特质和构建方法,本节中将深入了解 ApplicationBuilder 以窥探 IApplicationBuilder 真相
public interface IApplicationBuilder
{
IServiceProvider ApplicationServices { get; set; }
IFeatureCollection ServerFeatures { get; }
IDictionary<string, object?> Properties { get; }
IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
IApplicationBuilder New();
RequestDelegate Build();
}
管道机制
该机制是.NET最关键的机制之一,贯彻整个APP生命周期,但他的实现,简单巧妙的让人惊叹。
首先在内部维护了一个 Func<RequestDelegate, RequestDelegate> 集合
private readonly List<Func<RequestDelegate, RequestDelegate>> _components = new List<Func<RequestDelegate, RequestDelegate>>();
Func<RequestDelegate, RequestDelegate> 还有一个美腻的别名叫:中间件,UseMiddleware 的本质,就是 IApplicationBuilder.Use,调用 Use 其实就是添加一个中间件到集合
public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
this._components.Add(middleware);
return (IApplicationBuilder) this;
}
最终在 Build 生成此应用程序用于处理HTTP请求的委托。
public RequestDelegate Build()
{
RequestDelegate requestDelegate = (RequestDelegate) (context =>
{
Endpoint endpoint = context.GetEndpoint();
if (endpoint?.RequestDelegate != null)
throw new InvalidOperationException("The request reached the end of the pipeline without executing the endpoint: '" + endpoint.DisplayName + "'. Please register the EndpointMiddleware using 'IApplicationBuilder.UseEndpoints(...)' if using routing.");
context.Response.StatusCode = 404;
return Task.CompletedTask;
});
for (int index = this._components.Count - 1; index >= 0; --index)
requestDelegate = this._components[index](requestDelegate);
return requestDelegate;
}
为什么要倒着循环呢?这是因为在ASP.NET Core中,中间件的执行顺序是按照它们在ApplicationBuilder中注册的顺序来决定的。后注册的中间件会在前注册的中间件之前执行,这就是经典的洋葱模型

Properties&Features
Properties 是一个字典,用于在中间件之间共享数据。
public IDictionary<string, object?> Properties { get; }
为了防止在中间件中修改 ApplicationBuilder 对象的状态,实现了一个原型模型:仅复制 Properties
public IApplicationBuilder New() => (IApplicationBuilder) new ApplicationBuilder(this);
private ApplicationBuilder(ApplicationBuilder builder) => this.Properties = (IDictionary<string, object>) new CopyOnWriteDictionary<string, object>(builder.Properties, (IEqualityComparer<string>) StringComparer.Ordinal);
Features 用于获取应用程序Server提供的一组HTTP features,如果程序没有指定Server,则返回空集合
public interface IFeatureCollection : IEnumerable<KeyValuePair<Type, object>>, IEnumerable
在 ApplicationBuilder 中 Features 直接引用 Properties,他们两者基本等价。而在 WebApplication 中,通过 IServer 提供
IFeatureCollection ServerFeatures => this._host.Services.GetRequiredService<IServer>().Features;
IServer是服务器知识,看同学们述求,考虑是否讲
IServiceProvider
IServiceProvider 用于访问应用程序服务容器,位于 System 命名空间,在整个 .NET 中举重若轻。它的功能非常简洁,只做一件事情,仅有一个方法,用于从服务容器中获取给定服务的实现。
public interface IServiceProvider
{
/// <summary>Gets the service object of the specified type.</summary>
/// <param name="serviceType">An object that specifies the type of service object to get.</param>
/// <returns>A service object of type <paramref name="serviceType" />.
/// -or-
/// <see langword="null" /> if there is no service object of type <paramref name="serviceType" />.</returns>
object? GetService(Type serviceType);
}
服务容器化,横空出世;依赖注入,孕育而生
.NET 8 IApplicationBuilder详解的更多相关文章
- net core 中间件详解及项目实战
net core 中间件详解及项目实战 前言 在上篇文章主要介绍了DotNetCore项目状况,本篇文章是我们在开发自己的项目中实际使用的,比较贴合实际应用,算是对中间件的一个深入使用了,不是简单的H ...
- 在ASP.NET 5应用程序中的跨域请求功能详解
在ASP.NET 5应用程序中的跨域请求功能详解 浏览器安全阻止了一个网页中向另外一个域提交请求,这个限制叫做同域策咯(same-origin policy),这组织了一个恶意网站从另外一个网站读取敏 ...
- Middleware详解
Middleware详解 在第1章项目结构分析中,我们提到Startup.cs作为整个程序的入口点,等同于传统的Global.asax文件,即:用于初始化系统级的信息(例如,MVC中的路由配置).本章 ...
- IdentityServer4实战 - JWT Token Issuer 详解
原文:IdentityServer4实战 - JWT Token Issuer 详解 一.前言 本文为系列补坑之作,拖了许久决定先把坑填完. 下文演示所用代码采用的 IdentityServer4 版 ...
- 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入
系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...
- [转帖]ASP.NET Core 中间件(Middleware)详解
ASP.NET Core 中间件(Middleware)详解 本文为官方文档译文,官方文档现已非机器翻译 https://docs.microsoft.com/zh-cn/aspnet/core/ ...
- Asp.Net Core 中IdentityServer4 实战之角色授权详解
一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
随机推荐
- 使用 Docker Compose 安装 APISIX
1.基本概念 APISIX 是 Apache 下的一款云原生的 API 网关,支持全生命周期的 API 管理,在应用中可以作为所有 API 调用的统一入口. APISIX 有一些基础概念如下: Ups ...
- 力扣579(MySQL)-查询员工的累积薪水(困难)
题目: Employee 表保存了一年内的薪水信息. 请你编写 SQL 语句,对于每个员工,查询他除最近一个月(即最大月)之外,剩下每个月的近三个月的累计薪水(不足三个月也要计算). 结果请按 Id ...
- 力扣185(MySQL)-部门工资前三高的所有员工(困难)
题目: 表: Employee 表: Department 公司的主管们感兴趣的是公司每个部门中谁赚的钱最多.一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 . 编写一个S ...
- 链栈的实现 C语言/C++
堆栈的链式存储C/C++实现--链栈 与顺序栈相比,链栈的优点在于不存在栈满上溢的问题.链栈通常使用单链表实现,进栈.出栈操作就是在单链表表头的 插入.删除操作.用单链表实现链栈时,使用不带头结点的单 ...
- AI让边缘更智能 边缘让AI无处不在
简介: 城市管理和城市服务逐步走向智能化,智慧化.到2019底,全国100%的副省级城市,95%以上的地级市,以及50%以上的县级市均提出建设新型智慧城市,并已经有32个主要城市成立了专门的大数据管 ...
- [Blockchain] 去中心化与互联网分布式的联系与区别
去中心化和传统分布式都是多机应用,这是它们的共同之处,但是背后有着不一样的用途. 我们所理解的传统分布式及其应用可以解决两个问题:冗余备份/扩容 和 并行计算. 而去中心化应用的目的是维护不可逆转数据 ...
- OpenAI未至,Open-Sora再度升级!已支持生成16秒720p视频
Open-Sora 在开源社区悄悄更新了!现在支持长达 16 秒的视频生成,分辨率最高可达 720p,并且可以处理任何宽高比的文本到图像.文本到视频.图像到视频.视频到视频和无限长视频的生成需求.我们 ...
- 在.Net中操作redis
在.Net中操作redis 一.环境 .Net 7 redis 7.2.4 二.所需类包 StackExchange.Redis 三.连接redis信息 appsettings.json配置redis ...
- sql计算列中并非零值的平均值
avg不考虑空值 AVG (NULLIF(Value, 0)) NULLIF(expression, expression) 如果两个 expression 相等,则返回 NULL,该 NULL 为第 ...
- ORA-600 [kkqjpdpvpd: no join pred found.]
场景 一个比较大的sql查询,报出了ORA-600 [kkqjpdpvpd: no join pred found.] 解决方法: 根据metalink提供的解决思路.当于当前session,执行如下 ...