首页 > 其他分享 >IApplicationBuilder详解

IApplicationBuilder详解

时间:2023-11-07 20:12:50浏览次数:34  
标签:ApplicationBuilder object 中间件 IApplicationBuilder Properties 详解 public

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

​ 服务容器化,横空出世;依赖注入,孕育而生

标签:ApplicationBuilder,object,中间件,IApplicationBuilder,Properties,详解,public
From: https://www.cnblogs.com/xiaolipro/p/17815831.html

相关文章

  • RequestContextHolder详解(获取request对象的四种方法)
    方法1、Controller中加参数来获取request注意:只能在Controller中加入request参数。一般,我们在Controller中加参数获取HttpServletRequest,如下所示:@RestController@RequestMapping("/gap")publicclassPlantTraceController{@PostMapping("/plantTrace")publicResult......
  • JS之splice()方法详解
    JS中splice方法可以用来对js的数组进行删除,添加,替换等操作。1.删除功能,第一个参数为第一项位置,第二个参数为要删除几个;使用方法:array.splice(index,num),返回值为删除的内容,结果值为array2.插入功能,第一个参数(插入位置),第二个参数(0),第三个参数(插入的项)。使用方法:array.splice(index,0,......
  • OpenGL 坐标系统详解
    GL中的坐标系是标准设备坐标,即他的每个坐标轴的取值范围都是[-1.0,1.0]。通常,我们输入到顶点着色器中的顶点坐标都会被转换为标准化设备坐标,然后进行光栅化,转变成屏幕坐标。然而事实上,从顶点坐标到屏幕坐标是一个较为复杂的过程。总体来讲为了某些计算更加方便,会经过5个坐标系统的......
  • ADC-过零检测详解
    ADC-过零检测详解1、反电动势波形的起源下图展示了内转子磁极的磁感应强度B的分布情况。定义磁感应强度方向向外为正在0°的时候,处于正反方向交界处,磁感应强度为零;然后开始线性增加,在A点时达到最大然后一直保持恒定值不变,直到B点开始下降,到180°的时候下降到零。然后开始负......
  • 2、Text组件详解
    TextStyle的参数 //代码块importMimport'package:flutter/material.dart';voidmain(){runApp(MaterialApp(home:Scaffold(appBar:AppBar(title:constText("你好Flutter")),body:constMyApp(),),));}//代码块statelessWclassMyAppexten......
  • vmstat命令详解
    各种unix平台下iostat与vmstst说明vmstat是VirtualMeomoryStatistics(虚拟内存统计)的缩写,是实时系统监控工具。该命令通过使用knlist子程序和/dev/kmen伪设备驱动器访问这些数据,输出信息直接打印在屏幕。vmstat反馈的与CPU相关的信息包括:(1)多少任务在运行(2)CPU使用的情况(3)CPU收到......
  • 神经网络基础篇:详解向量化逻辑回归(Vectorizing Logistic Regression)
    向量化逻辑回归讨论如何实现逻辑回归的向量化计算。这样就能处理整个数据集,甚至不会用一个明确的for循环就能实现对于整个数据集梯度下降算法的优化首先回顾一下逻辑回归的前向传播步骤。所以,如果有\(m\)个训练样本,然后对第一个样本进行预测,需要这样计算。计算\(z\),正在使......
  • Azure Data Factory(十)Data Flow 组件详解
    一,引言随着大数据技术的不断发展,数据处理和分析变得越来越重要。为了满足企业对数据处理的需求,微软推出了AzureDataFactory(ADF),它是一个云端的数据集成服务,用于创建、安排和管理数据工作流。在本文中,我们将重点介绍AzureDataFactory的数据流(DataFlow),以及它如何帮助......
  • 【Redis使用手册】一年多来redis使用markdow笔记总结,第(2)篇:Redis命令操作详解
    Redis是一个高性能的key-value数据库。本文会让你知道:什么是nosql、Redis的特点、如何修改常用Redis配置、写出Redis中string类型数据的增删改查操作命令、写出Redis中hash类型数据的增删改查相关命令、说出Redis中list保存的数据类型、使用StrictRedis对象对string类型数据......
  • WM_CLOSE、WM_DESTROY、WM_QUIT及各种消息投递函数详解
     对WM_CLOSE、WM_DESTROY、WM_QUIT及各种消息投递函数的功能及区别做出了分析比对,有助于读者更好的对消息投递函数加以理解。详情如下:一、WM_CLOSE、WM_DESTROY、WM_QUIT区别WM_CLOSE:关闭应用程序窗口WM_DESTROY:关闭应用程序WM_QUIT:关闭消息循环只有关闭了消息循环,应用程序......