ASP.Net Core管道和注册中间件精简版

本文实现旨在实现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 框架 。

posted @ 2021-07-15 09:11  天众师兄  阅读(88)  评论(0编辑  收藏  举报