本文实现旨在实现ASP.Net Core管道和注册中间件的一个精简版。直接上代码。
1、添加 WebHostBuilder 类。
public class WebHostBuilder { private HttpListenerServer _httpListener; private readonly List<Action<ApplicationBuilder>> _configures = new List<Action<ApplicationBuilder>>(); public WebHost Build() { var builder = new ApplicationBuilder(); foreach (var item in _configures) { item(builder); } return new WebHost(_httpListener, builder.Build()); } public WebHostBuilder Configure(Action<ApplicationBuilder> configure) { _configures.Add(configure); return this; } public WebHostBuilder UseServer(HttpListenerServer server) { _httpListener = server; return this; } }
2、添加 WebHost 类。
public class WebHost { private readonly HttpListenerServer _httpListener; private readonly RequestDelegate _requestDelegate; public WebHost(HttpListenerServer server, RequestDelegate requestDelegate) { _httpListener = server; _requestDelegate = requestDelegate; } public Task StartAsync() => _httpListener.StartAsync(_requestDelegate); }
3、添加 HttpListenerServer 类。
public class HttpListenerServer { private readonly HttpListener _httpListener;// System.Net命名空间下 private readonly string[] _urls; public HttpListenerServer(params string[] urls) { _httpListener = new HttpListener(); _urls = urls.Any() ? urls : new string[] { "http://localhost:5007/", "http://127.0.0.1:5007/" }; } public async Task StartAsync(RequestDelegate handler) { Array.ForEach(_urls, url => _httpListener.Prefixes.Add(url)); _httpListener.Start(); while (true) { HttpListenerContext listenerContext = await _httpListener.GetContextAsync();// System.Net命名空间下 HttpRequest httpRequest = new HttpRequest(); httpRequest.Url = listenerContext.Request.Url; httpRequest.Headers = listenerContext.Request.Headers; httpRequest.Body = listenerContext.Request.InputStream; HttpResponse httpResponse = new HttpResponse(listenerContext); httpResponse.Headers = listenerContext.Response.Headers; httpResponse.StatusCode = listenerContext.Response.StatusCode; var httpContext = new HttpContext(httpRequest, httpResponse); await handler(httpContext); listenerContext.Response.Close(); } } }
4、添加 ApplicationBuilder 类。
public class ApplicationBuilder { private readonly List<Func<RequestDelegate, RequestDelegate>> _middlewares = new List<Func<RequestDelegate, RequestDelegate>>(); public RequestDelegate Build() { _middlewares.Reverse(); return httpContext => { RequestDelegate next = _ => { _.Response.StatusCode = 404; _.Response.ContentType = "text/plain;charset=utf-8"; _.Response.WriteAsync("您访问的页面逃走了"); return Task.CompletedTask; }; foreach (var item in _middlewares) { next = item(next); } return next(httpContext); }; } public ApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware) { _middlewares.Add(middleware); return this; } }
5、添加 RequestDelegate 类。
public delegate Task RequestDelegate(HttpContext httpContext);
6、添加 HttpContext 类。
public class HttpContext { public HttpRequest Request { get; } public HttpResponse Response { get; } public HttpContext(HttpRequest httpRequest, HttpResponse httpResponse) { Request = httpRequest; Response = httpResponse; } }
7、添加 HttpRequest 类。
public class HttpRequest { public Uri Url { get; set; } public NameValueCollection Headers { get; set; } public Stream Body { get; set; } }
8、添加 HttpResponse 类。
public class HttpResponse { private HttpListenerContext httpListener;// System.Net命名空间下 public HttpResponse(HttpListenerContext listenerContext) { httpListener = listenerContext; } public NameValueCollection Headers { get; set; } public Stream Body { get { return httpListener.Response.OutputStream; } } public int StatusCode { get; set; } public string ContentType { get { return httpListener.Response.ContentType; } set { httpListener.Response.ContentType = value; } } }
9、添加扩展方法 ExtensionMethod 。
public static class ExtensionMethod { public static Task WriteAsync(this HttpResponse response, string contents) { var buffer = Encoding.UTF8.GetBytes(contents); return response.Body.WriteAsync(buffer, 0, buffer.Length); } }
10、新建一个控制台项目测试。
class Program { static async Task Main(string[] args) { await new WebHostBuilder() .UseServer(new HttpListenerServer(@"http://localhost:5003/")) //.Configure(app => { }) .Configure(app => app.Use(F1) .Use(F2) .Use(F3)) .Build() .StartAsync(); } public static RequestDelegate F1(RequestDelegate requestDelegate) { return context => { context.Response.ContentType = "text/plain;charset=utf-8"; context.Response.WriteAsync("访问F1"); return requestDelegate(context); }; } public static RequestDelegate F2(RequestDelegate requestDelegate) { return context => { context.Response.ContentType = "text/plain;charset=utf-8"; context.Response.WriteAsync("访问F2"); return requestDelegate(context); }; } public static RequestDelegate F3(RequestDelegate requestDelegate) { return async context => { context.Response.ContentType = "text/plain;charset=utf-8"; await context.Response.WriteAsync("访问F3"); }; } }
11、本文所建项目都是使用 .Net 5.0 框架 。