写一个简版 asp.net core
source link: http://mp.weixin.qq.com/s?__biz=MzAxMjE2NTMxMw%3D%3D&%3Bmid=2456606176&%3Bidx=1&%3Bsn=89beddf015e2eaa79db23cb72d98d7a6
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
动手写一个简版 asp.net core
Intro
之前看到过蒋金楠老师的一篇 200 行代码带你了解 asp.net core 框架,最近参考蒋老师和 Edison 的文章和代码,结合自己对 asp.net core 的理解 ,最近自己写了一个 MiniAspNetCore ,写篇文章总结一下。
HttpContext
HttpContext
可能是最为常用的一个类了, HttpContext
是请求上下文,包含了所有的请求信息以及响应信息,以及一些自定义的用于在不同中间件中传输数据的信息
来看一下 HttpContext
的定义:
HttpRequest
即为请求信息对象,包含了所有请求相关的信息,
HttpResponse
为响应信息对象,包含了请求对应的响应信息
RequestServices
为 asp.net core 里的 RequestServices
,代表当前请求的服务提供者,可以使用它来获取具体的服务实例
Features
为 asp.net core 里引入的对象,可以用来在不同中间件中传递信息和用来解耦合
,下面我们就来看下 HttpRequest
和 HttpResponse
是怎么实现的
HttpRequest:
HttpResponse:
Features
上面我们提供我们可以使用 Features
在不同中间件中传递信息和解耦合
由上面 HttpRequest
/ HttpResponse
的代码我们可以看出来, HttpRequest
和 HttpResponse
其实就是在 IRequestFeature
和 IResponseFeature
的基础上封装了一层,真正的核心其实是 IRequestFeature
/ IResponseFeature
,而这里使用接口就很好的实现了解耦,可以根据不同的 WebServer 使用不同的 RequestFeature
/ ResponseFeature
,来看下 IRequestFeature
/ IResponseFeature
的实现
这里的实现和 asp.net core 的实际的实现方式应该不同,asp.net core 里 Headers 同一个 Header 允许有多个值,asp.net core 里是 StringValues 来实现的,这里简单处理了,使用了一个 NameValueCollection
对象
上面提到的 Features
是一个 IFeatureCollection
对象,相当于是一系列的 Feature
对象组成的,来看下 FeatureCollection
的定义:
这里 IFeatureCollection
直接实现 IDictionary<Type,object>
,通过一个字典 Feature 类型为 Key,Feature 对象为 Value 的字典来保存
为了方便使用,可以定义两个扩展方法来方便的Get/Set
Web服务器
上面我们已经提到了 Web 服务器通过 IRequestFeature
/ IResponseFeature
来实现不同 web 服务器和应用程序的解耦,web 服务器只需要提供自己的 RequestFeature
/ ResponseFeature
即可
为了抽象不同的 Web 服务器,我们需要定义一个 IServer
的抽象接口,定义如下:
IServer
定义了一个 StartAsync
方法,用来启动 Web服务器,
StartAsync
方法有两个参数,一个是 requestHandler,是一个用来处理请求的委托,另一个是取消令牌用来停止 web 服务器
示例使用了 HttpListener
来实现了一个简单 Web 服务器, HttpListenerServer
定义如下:
HttpListenerServer
实现的 RequestFeature
/ ResponseFeatue
为了方便使用,为 HttpListenerContext
定义了两个扩展方法,就是上面 HttpListenerServer
中的 GetRequestFeature
/ GetResponseFeature
:
RequestDelegate
在上面的 IServer
定义里有一个 requestHandler 的 对象,在 asp.net core 里是一个名称为 RequestDelegate
的对象,而用来构建这个委托的在 asp.net core 里是 IApplicationBuilder
,这些在蒋老师和 Edison 的文章和代码里都可以看到,这里我们只是简单介绍下,我在 MiniAspNetCore 的示例中没有使用这些对象,而是使用了自己抽象的 PipelineBuilder
和原始委托实现的
asp.net core 里 RequestDelegate
定义:
其实和我们上面定义用的 Func<HttpContext,Task>
是等价的
IApplicationBuilder
定义:
我们这里没有定义 IApplicationBuilder
,使用了简化抽象的 IAsyncPipelineBuilder
,定义如下:
对于 asp.net core 的中间件来说 ,上面的 TContext
就是 HttpContext
,替换之后也就是下面这样的:
是不是和 IApplicationBuilder
很像,如果不像可以进一步把 Func<HttpContext,Task>
使用 RequestDelegate
替换
最后再将接口名称替换一下:
至此,就完全可以看出来了,这 IAsyncPipelineBuilder<HttpContext>
就是一个简版的 IApplicationBuilder
IAsyncPipelineBuilder
和 IApplicationBuilder
的作用是将注册的多个中间件构建成一个请求处理的委托
中间件处理流程:
更多关于 PipelineBuilder 构建中间件的信息可以查看 让 .NET 轻松构建中间件模式代码 了解更多
WebHost
通过除了 Web 服务器之外,还有一个 Web Host 的概念,可以简单的这样理解,一个 Web 服务器上可以有多个 Web Host,就像 IIS/nginx (Web Server) 可以 host 多个站点
可以说 WebHost 离我们的应用更近,所以我们还需要 IHost
来托管应用
WebHost
定义:
为了方便的构建 Host
对象,引入了 HostBuilder
来方便的构建一个 Host
,定义如下:
WebHostBuilder
:
这里的示例我在 IHostBuilder
里增加了一个 Initialize
的方法来做一些初始化的操作,我觉得有些数据初始化配置初始化等操作应该在这里操作,而不应该在 Startup
的 Configure
方法里处理,这样 Configure
方法可以更纯粹一些,只配置 asp.net core 的请求管道,这纯属个人意见,没有对错之分
这里 Host 的实现和 asp.net core 的实现不同,有需要的可以深究源码,在 asp.net core 2.x 的版本里是有一个 IWebHost
的,在 asp.net core 3.x 以及 .net 5 里是没有 IWebHost
的取而代之的是通用主机 IHost
, 通过实现了一个 IHostedService
来实现 WebHost
的
Run
运行示例代码:
在示例项目目录下执行 dotnet run
,并访问 http://localhost:5100/
:
仔细观察浏览器 console
或 network
的话,会发现还有一个请求,浏览器会默认请求 /favicon.ico
获取网站的图标
因为我们针对这个请求没有任何中间件的处理,所以直接返回了 404
在访问 /test
,可以看到和刚才的输出完全不同,因为这个请求走了另外一个分支,相当于 asp.net core 里 Map
/ MapWhen
的效果,另外 Run
代表里中间件的中断,不会执行后续的中间件
More
上面的实现只是我在尝试写一个简版的 asp.net core 框架时的实现,和 asp.net core 的实现并不完全一样,如果需要请参考源码,上面的实现仅供参考,上面实现的源码可以在 Github 上获取 https://github.com/WeihanLi/SamplesInPractice/tree/master/MiniAspNetCore
asp.net core 源码:https://github.com/dotnet/aspnetcore
Reference
-
https://www.cnblogs.com/artech/p/inside-asp-net-core-framework.html
-
https://www.cnblogs.com/artech/p/mini-asp-net-core-3x.html
-
https://www.cnblogs.com/edisonchou/p/aspnet_core_mini_implemention_introduction.html
-
https://github.com/WeihanLi/SamplesInPractice/tree/master/MiniAspNetCore
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK