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 注册一下。

原文地址:https://www.cnblogs.com/jasontarry/p/15376267.html