• net core 中间件 MiddleWare 三种方式


       

    直接通过反射 找到类  

    RequestDelegate  和  InvokeAsync  这2个都是固定写法 框架帮我们写死的 ,
    如果看是不是中间件,框架先检查 参数 有没有InvokeAsync方法和第一个参数必须是RequestDelegate

    源码如下 :

     

       app.UseMiddleware<OnetMiddleWare>();

        public class OneMiddleWare
        {
            private readonly RequestDelegate _next;
    
            public OneMiddleWare(RequestDelegate next)
            {
                _next = next;
            }
    
            public async Task InvokeAsync(HttpContext context)
            {
                await context.Response.WriteAsync($"{nameof(OneMiddleWare)},Hello World1!<br/>");
    
                await _next(context);
    
                await context.Response.WriteAsync($"{nameof(OneMiddleWare)},Hello World2!<br/>");
            }
        }


    app.UseMiddleware<TwoMiddleWare>(); 是实现 IMiddleware 接口 TwoMiddleWare类型的初始化是请求来了之后才发生, 实现IMiddleware,就不能有参数--而且还得IOC注册

        public class TwoMiddleWare : IMiddleware, IDisposable
        {
            private readonly ILogger _logger;
    
            public TwoMiddleWare(ILogger<TwoMiddleWare> logger)
            {
                this._logger = logger;
            }
    
            public async Task InvokeAsync(HttpContext context, RequestDelegate next)
            {
                this._logger.LogWarning($"{nameof(TwoMiddleWare)},Hello World1!<br/>");
    
                await context.Response.WriteAsync($"{nameof(TwoMiddleWare)},Hello World1!<br/>");
                await next(context);
                await context.Response.WriteAsync($"{nameof(TwoMiddleWare)},Hello World2!<br/>");
            }
    
            public void Dispose()
            {
                Console.WriteLine("释放需要释放的资源");
            }
        }


    app.UseMiddleware<ThreeMiddleWare>("tet");  可以带参数   前面第一个参数 和第三个参数不是ioc 注入的 是传入的    

     ,而第二个参数是ioc  生成的。我们没有service 里面 添加ThreeMiddleWare 的注册

        public class ThreeMiddleWare
        {
            private readonly RequestDelegate _next;
            private readonly ILogger _logger;
            private readonly string _Message;
    
            public ThreeMiddleWare(RequestDelegate next, ILogger<ThreeMiddleWare> logger, string message)
            {
                this._next = next;
                this._logger = logger;
                this._Message = message;
            }
            /// <summary>
            /// 1 方法名字Invoke或者InvokeAsync
            /// 2 返回类型必须是Task
            /// </summary>
            /// <param name="context"></param>
            /// <returns></returns>
            public async Task Invoke(HttpContext context)
            {
                Console.WriteLine($"{nameof(ThreeMiddleWare)}---{this._Message}");
                if (!context.Request.Path.Value.Contains("jason"))
                {
                    await context.Response.WriteAsync($"{nameof(ThreeMiddleWare)}This is End<br/>");
                }
                else
                {
                    await context.Response.WriteAsync($"{nameof(ThreeMiddleWare)},Hello World ThreeMiddleWare!<br/>");
                    await _next(context);
                    await context.Response.WriteAsync($"{nameof(ThreeMiddleWare)},Hello World ThreeMiddleWare!<br/>");
                }
            }
        }

    在bulid 的时候 才执行里面的 委托方法 。

     结论  one 和three  都是在bulid 的时候 已经初始化好中间件了 已经通过反射创建好了,而通过接口的twomiddleware 是请求来的时候,实例化这个类的,2者还是有区别,如果想做资源的释放可以用第二种接口形式的。相应时候实例化,用过gc掉,如果用接口的形式还要注册一下 services.AddSingleton<TwoMiddleWare>(); 第一第三种是通过反射创建对象的,第二种是ioc 所以这就解释了为什么要在ConfigureServices 注册一下。

  • 相关阅读:
    ICPC-Beijing 2006 狼抓兔子
    【模板】多项式求逆
    AHOI2014/JSOI2014 奇怪的计算器
    Hnoi2013 切糕
    Ahoi2014&Jsoi2014 支线剧情
    bzoj3774 最优选择
    WC2019游记
    HNOI2007 分裂游戏
    bzoj1457 棋盘游戏
    poj2484 A Funny Game
  • 原文地址:https://www.cnblogs.com/jasontarry/p/15376267.html
Copyright © 2020-2023  润新知