在上节中我们已经得知 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

​ 在 ApplicationBuilderFeatures 直接引用 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详解的更多相关文章

  1. net core 中间件详解及项目实战

    net core 中间件详解及项目实战 前言 在上篇文章主要介绍了DotNetCore项目状况,本篇文章是我们在开发自己的项目中实际使用的,比较贴合实际应用,算是对中间件的一个深入使用了,不是简单的H ...

  2. 在ASP.NET 5应用程序中的跨域请求功能详解

    在ASP.NET 5应用程序中的跨域请求功能详解 浏览器安全阻止了一个网页中向另外一个域提交请求,这个限制叫做同域策咯(same-origin policy),这组织了一个恶意网站从另外一个网站读取敏 ...

  3. Middleware详解

    Middleware详解 在第1章项目结构分析中,我们提到Startup.cs作为整个程序的入口点,等同于传统的Global.asax文件,即:用于初始化系统级的信息(例如,MVC中的路由配置).本章 ...

  4. IdentityServer4实战 - JWT Token Issuer 详解

    原文:IdentityServer4实战 - JWT Token Issuer 详解 一.前言 本文为系列补坑之作,拖了许久决定先把坑填完. 下文演示所用代码采用的 IdentityServer4 版 ...

  5. 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入

    系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...

  6. [转帖]ASP.NET Core 中间件(Middleware)详解

    ASP.NET Core 中间件(Middleware)详解   本文为官方文档译文,官方文档现已非机器翻译 https://docs.microsoft.com/zh-cn/aspnet/core/ ...

  7. Asp.Net Core 中IdentityServer4 实战之角色授权详解

    一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,用到了IdentityServer4的授权,改造过程中发现比较适合基于Role角 ...

  8. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  9. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  10. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

随机推荐

  1. vue项目中嵌入软键盘(中文/英文)

    键盘效果是这样,样式可以自己调整.gittee地址:https://gitee.com/houxianzhou/VirtualKeyboard.git步骤1 安装使用jQuery npm instal ...

  2. 记一次 Go 调用系统命令出现的问题分析

    首先在程序中封装了下面一个函数用来执行系统命令: // 执行系统命令 func executeCommand(command string, output, outerr io.Writer) err ...

  3. 力扣367(java&python)-有效的完全平方数(简单)

    题目: 给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false . 进阶:不要 使用任何内置的库函数,如  sqrt . 示例 1: 输入: ...

  4. AI让边缘更智能 边缘让AI无处不在

    ​简介: 城市管理和城市服务逐步走向智能化,智慧化.到2019底,全国100%的副省级城市,95%以上的地级市,以及50%以上的县级市均提出建设新型智慧城市,并已经有32个主要城市成立了专门的大数据管 ...

  5. 如何高效学习 Kubernetes 知识图谱?

    ​简介: Kubernetes 知识图谱遵循云原生人才学习路径搭建课程体系框架,及人才发展路线设置不同阶段,由浅入深,帮助云原生人才学习容器基础.Kuternetes 网络.存储.资源对象.服务发现. ...

  6. Linux内核社区迁移到github?

    简介: github是目前最火的开源软件代码托管平台,那么Linux内核社区能否迁移到github上呢?Intel的Daniel Vetter写了一篇关于这个问题的博客,他给出的答案是NO.至于这个答 ...

  7. [Blockchain] Cosmos Starport 101 - 为你的新数据类型 生成代码

    # 项目模板 $ starport app github.com/hello/planet --address-prefix your_new_prefix 项目目录结构的说明看这里: https:/ ...

  8. 通过WebRTC简单实现媒体共享

    通过WebRTC简单实现媒体共享 媒体协商 在设置本地描述符(offer/answer)前,我们总是需要将媒体添加到连接中,只有这样在描述符中才能包含需要共享的媒体信息,除非你不需要共享媒体. 在实际 ...

  9. K8s控制器(8)---Deployment

    一.Deployment控制器概念.原理解读 1.1 Deployment概述 # Deployment官方文档 https://kubernetes.io/docs/concepts/workloa ...

  10. shell 调试方法

    shell 在 linux 系统中比较常见,简单的脚本可以看着确实没难度,但是当脚本功能复杂后,看起来就不那么流畅了,所以掌握一些调试方式还是很有必要的,这里我收集了一次常用的调试方式. shell调 ...