在上节中我们已经得知 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. List拖拽功能的实现

    概述   如何在HarmonyOS应用中实现一个可拖拽的列表组件,通过这个组件,用户可以拖动列表中的项并将其放置在新的位置,实现列表的动态排序.   核心功能   列表初始化:创建并填充列表数据. 拖 ...

  2. 手写一个Mybatis框架

    第一:Mybatis框架介绍 最近看了一篇关于Mybatis的文章,发现MyBatis框架的核心功能其实不难,无非就是动态代理和jdbc的操作,难的是写出可扩展,高聚合,低耦合的规范的代码. 本文手写 ...

  3. 《Effective C#》系列之(六)——提高多线程的性能

    一.综述 <Effective C#>中提高多线程性能的方法主要有以下几点: 避免锁竞争:锁的使用会导致线程阻塞,从而影响程序的性能.为了避免锁竞争,可以采用无锁编程技术,如CAS(Com ...

  4. 【译】Visual Studio Enterprise 中的代码覆盖率特性

    通过使用代码覆盖率功能,您可以发现您的测试需要改进的地方,并使您的软件更加健壮和可靠.在这篇文章中,我们将介绍我们在 Visual Studio Enterprise 2022 中引入的 Code C ...

  5. 简单、有效、全面的Kubernetes监控方案

    ​简介:近年来,Kubernetes作为众多公司云原生改造的首选容器化编排平台,越来越多的开发和运维工作都围绕Kubernetes展开,保证Kubernetes的稳定性和可用性是最基础的需求,而这其中 ...

  6. DevOps发布策略简介

    简介: DevOps追求更短的迭代周期.更高频的发布.但发布的次数越多,引入故障的可能性就越大.更多的故障将会降低服务的可用性,进而影响到客户体验.所以,为了保证服务质量,守好发布这个最后一道关,阿里 ...

  7. Javascript 机器学习的四个层次

    ​简介: Atwood定律说,凡是可以用Javascript实现的应用,最终都会用Javascript实现掉.作为最热门的机器学习领域,服务端是Python的主场,但是到了手机端呢?Android和i ...

  8. [FAQ] IDE: Goland 注释符后面添加空行

    如图所示,Code Style 对应语言 Go 勾选上注释空行的选项. Refer:Goland官网 Goland下载 Link:https://www.cnblogs.com/farwish/p/1 ...

  9. 1.权限控制RBAC

    官方参考地址:https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/#privilege-escalation-prev ...

  10. vue通过input选取apk文件上传,显示进度条

    <template> <div class=""> <form action="" method="post" ...