asp easp 开源框架_200行代码,7个对象——让你了解ASP.NET Core框架的本质

本文通过构建一个微型的ASP.NET Core框架,展示了 HttpContext、中间件、服务器适配等核心概念,揭示了请求处理管道的工作原理。作者强调简单设计,解释了如何使用HttpListenerServer、WebHostedService和WebHostBuilder来创建和管理请求处理流程。通过实例,读者可以了解如何注册中间件并构建应用程序。
摘要由CSDN通过智能技术生成
a34c281592a71026b740d767bbf1999e.png点击上方“蓝字”关注我们 8949943b86eb1a18ca8a724a25d891ef.png 一、中间件委托链

通过本篇文章,我将管道最核心的部分提取出来构建一个“迷你版”的ASP.NET Core框架。较之真正的ASP.NET Core框架,虽然重建的模拟框架要简单很多,但是它们采用完全一致的设计。为了能够在真实框架中找到对应物,在定义接口或者类型时会采用真实的名称,但是在API的定义上会做最大限度的简化。

HttpContext

一个HttpContext对象表示针对当前请求的上下文。要理解HttpContext上下文的本质,需要从请求处理管道的层面来讲。对于由一个服务器和多个中间件构成的管道来说,面向传输层的服务器负责请求的监听、接收和最终的响应,当它接收到客户端发送的请求后,需要将请求分发给后续中间件进行处理。对于某个中间件来说,完成自身的请求处理任务之后,在大部分情况下需要将请求分发给后续的中间件。请求在服务器与中间件之间,以及在中间件之间的分发是通过共享上下文的方式实现的。

如下图所示,当服务器接收到请求之后,会创建一个通过HttpContext表示的上下文对象,所有中间件都在这个上下文中完成针对请求的处理工作。那么一个HttpContext对象究竟会携带什么样的上下文信息?一个HTTP事务(Transaction)具有非常清晰的界定,如果从服务器的角度来说就是始于请求的接收,而终于响应的回复,所以请求和响应是两个基本的要素,也是HttpContext承载的最核心的上下文信息。

7c093a5672191cc1c7eb73a936c64c6d.png

我们可以将请求和响应理解为一个Web应用的输入与输出,既然HttpContext上下文是针对请求和响应的封装,那么应用程序就可以利用这个上下文对象得到当前请求所有的输入信息,也可以利用它完成我们所需的所有输出工作。所以,我们为ASP.NET Core模拟框架定义了如下这个极简版本的HttpContext类型。

public class HttpListenerFeature : IHttpRequestFeature, IHttpResponseFeature
{
private readonly HttpListenerContext _context;
public HttpListenerFeature(HttpListenerContext context)=> _context = context;

Uri IHttpRequestFeature.Url=> _context.Request.Url;
NameValueCollection IHttpRequestFeature.Headers=> _context.Request.Headers;
NameValueCollection IHttpResponseFeature.Headers=> _context.Response.Headers;
Stream IHttpRequestFeature.Body=> _context.Request.InputStream;
Stream IHttpResponseFeature.Body=> _context.Response.OutputStream;
int IHttpResponseFeature.StatusCode
{
get => _context.Response.StatusCode;
set => _context.Response.StatusCode = value;
}
}

如上面的代码片段所示,我们可以利用HttpRequest对象得到当前请求的地址、请求消息的报头集合和主体内容。利用HttpResponse对象,我们不仅可以设置响应的状态码,还可以添加任意的响应报头和写入任意的主体内容。

中间件

HttpContext对象承载了所有与当前请求相关的上下文信息,应用程序针对请求的响应也利用它来完成,所以可以利用一个Action类型的委托对象来表示针对请求的处理,我们姑且将它称为请求处理器(Handler)。但Action仅仅是请求处理器针对“同步”编程模式的表现形式,对于面向Task的异步编程模式,这个处理器应该表示成类型为Func的委托对象。

由于这个表示请求处理器的委托对象具有非常广泛的应用,所以我们为它专门定义了如下这个RequestDelegate委托类型,可以看出它就是对Func委托的表达。一个RequestDelegate对象表示的是请求处理器,那么中间件在模型中应如何表达?

public delegate Task RequestDelegate(HttpContext context);

作为请求处理管道核心组成部分的中间件可以表示成类型为Func的委托对象。换句话说,中间件的输入与输出都是一个RequestDelegate对象。我们可以这样来理解:对于管道中的某个中间件(下图所示的第一个中间件)来说,后续中间件组成的管道体现为一个RequestDelegate对象,由于当前中间件在完成了自身的请求处理任务之后,往往需要将请求分发给后续中间件进行处理,所以它需要将后续中间件构成的RequestDelegate对象作为输入。

5825fd73c26d4cd3482b11ac22ff63f1.png

当代表当前中间件的委托对象执行之后,如果将它自己“纳入”这个管道,那么代表新管道的RequestDelegate对象就成为该委托对象执行后的输出结果,所以中间件自然就表示成输入和输出类型均为RequestDelegate的Func对象。

中间件管道的构建

从事软件行业10多年来,笔者对架构设计越来越具有这样的认识:好的设计一定是“简单”的设计。所以在设计某个开发框架时笔者的目标是再简单点。上面介绍的请求处理管道的设计就具有“简单”的特质:Pipeline = Server + Middlewares。但是“再简单点”其实是可以的,我们可以将多个中间件组成一个单一的请求处理器。请求处理器可以通过RequestDelegate对象来表示,所以整个请求处理管道将具有更加简单的表达:Pipeline = Server + RequestDelegate。

4232dc184d92aaf990f0c32290d34ae0.png

表示中间件的Func对象向表示请求处理器的RequestDelegate对象之间的转换是通过IApplicationBuilder对象来完成的。从接口命名可以看出,IApplicationBuilder对象是用来构建“应用程序”(Applicatio

AspBox是一个方便快速开发ASP框架AspBox提供了大量实用的ASP通用过程及方法和子类,可以简化大部分的ASP操作。 AspBox还可以进拓展子类对象以增强自身功能。封装严谨,层层嵌套,提高了代码重复利用多次利用。 可以说AspBox是一个比较成型的可应用于开发人员快速开发的ASP开发框架ASP框架AspBox 1.3.2a 更新记录:2013-03-22 AB核心代码修整, 增加了公共调用 AB.Pub 核心 完善 AB.CacheType 属性设置 新增 AB.CacheClean 方法 新增 AB.FnAdd 别名: AB.FnSet 新增 AB.A.Avg, AB.A.Sub, AB.A.SpliceX 方法 修正 AB.A.Slice, AB.A.Splice, AB.A.SpliceX, AB.A.Fill  方法 拓展增强 AB.A.Walk 方法 修正 AB.C.CRight 方法 完善 AB.C.GetUrl 方法 新增 AB.C.Clone, AB.C.CallFunc, AB.C.Ws, AB.C.Wsn, AB.C.IsDim 等方法 新增 AB.Cache.Del 方法, 别名 AB.Cache(cacheName).Del 或 AB.Cache.Item(cacheName).Del 移除 AB.Json.xJSObjectToString, AB.Json.xJSArrayToString 方法 新增 AB.E.encodeURIComponent, AB.E.decodeURIComponent, AB.E.encodeURI, AB.E.decodeURI 方法 修正 设置 AB.Http.Charset 失效bug 拓展增强 AB.Char.Trim, AB.Char.LTrim, AB.Char.RTrim 方法 新增 AB.Time.ServerTime, AB.Time.LocalTime, AB.Time.ServerTimezone, AB.Time.LocalTimezone 方法 新增 AB.Time.ToUnixEpoch 方法别名 AB.Time.ToID 和 AB.Time.TimeID 新增 AB.Time.FromUnixEpoch 方法别名 AB.Time.FromID 和 AB.Time.FromTimeID 修复 AB.Url.Go 函数 Bug 改进 AB.Xml.Find 方法,使其支持 AB.Xml(selector).Length 为0情况 新增 AB.Xml.Length, AB.Xml.Count 方法 新增 AB.Xml(selector).ChildNodes 方法 AspBox核心主要包含了这么些核心: A处理Array数组 C通用函数类 Cookie操作类 Catch缓存类操作 Char字符处理类 D一般函数库 DB数据操作类 DBO数据操作对象 E加密模块(包含了Md5,Base64,SHA-1加密及收集了一些加密函数块) Form表单处理块 Fso操作类操作 Html控件 Http对XMLHttp处理块 Error错误处理块 Json处理块 jsLib(JS脚本核心引用操作) List处理各种List对象 Mail邮件处理块 PY拼音转换模块 Rnd随机数函数块 Session操作类 Sc脚本执操作模块 Time时间操作块 Tpl模板类 Up,Upload上传处理块 Url处理块 X扩展块 Xml处理XML块 以及其他一些调用方法如aspjpeg组件操作,无惧上传类,艾恩上传类等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值