• OWIN katana注册中间件的几种写法


    首先特别说明下在startup中注册完中间件的两个注意事项,看到有人写的东西有误导人的作用。关于startup启动发现类的内容,参照这里 http://www.asp.net/aspnet/overview/owin-and-katana/owin-startup-class-detection

    1. 使用IApplicationBuilder.User注册中间件是有先后顺序关系的。

    2. 注册的中间件的执行过程是这样的:输入初始化是按照顺序来的,输出执行是反顺序来的。

    请求发生-->初始化中间件1--->初始化中间件n-->app忽略中间件方法,直接响应输出--------->中间件n Invoke执行处理-->中间件1 Invoke执行处理--->响应输出

    进入正文

    OWIN middleware 必须是具有以下代码特征,要么是直接在startup类中直接注册,要么就是写的中间件类中方法返回。

    Func<IDictionary<string, object>, Task> //这个function具有一个上下文的字典参数(OWIN environment dictionary),并返回Task

    这段特征码中的IDictionary<string, object>其实已经被katana的server层包装成字典形式的请求上下文(HttpContext)IOwinContext,可以使用上下文属性environment访问字典值

     我们会以这种形式注册中间件

    IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware); //middleware 可以是委托 or  类型 or 实例

    中间件注册进入管道,由于中间件返回一个Task,就能保证管道在处理的时候能找到下一个执行的Task就是下边代码中的next参数,那么next就是已知的第一个RequestDelegate参数来处理请求和响应。Task就是返回的具有中间件特征的中间件。


    下面我们看下第一种写法

    app.Use(new Func<RequestDelegate, RequestDelegate>(next => (async context =>
    {
        Console.WriteLine("初始化组件开始");
        await next.Invoke(context);
        Console.WriteLine("管道下步执行完毕");
    })));

    以上代码中会在请求时在控制台输出“初始化组件开始”,当组件的下一个步骤执行完毕后,会再打印出“管道下步执行完毕”。

    有时候组件里没啥规则,但是也必须接受next作为参数,但是可以忽略它,并且仍然需要返回一个task,所以可以这样写

    app.Use(new Func<RequestDelegate, RequestDelegate>(ignoreNext => (content=>
    {
        Console.WriteLine("The request ends with me!");
        return Task.FromResult(0);
    })));


    第二种写法
    是将已有的方法传递给委托。如果你有一些逻辑需要抽象出来,但又不想单独写一个中间件类,这个写法就比较合适

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Use(new Func<RequestDelegate, RequestDelegate>(next => content=> Invoke(next, content)));
        }
    
        private async Task Invoke(RequestDelegate next, IDictionary<string, object> environment) 
        {
            Console.WriteLine("初始化组件开始");
            await next.Invoke(environment);
            Console.WriteLine("管道下步执行完毕");
        }
    }

    如果使用一下代码注册组件,那么久必须写一个实际的中间件类了

    app.Use(typeof(LoggingMiddleware));

    或者以中间件实例来注册

    app.Use(new LoggingMiddleware());

    第三种写法是实现一个实际的中间件类

    public class LoggingMiddleware
    {
        private RequestDelegate next;
    
        public LoggingMiddleware(RequestDelegate next)
        {
            this.next = next;
        }
    
        public async Task Invoke(IDictionary<string, object> environment)
        {
            Console.WriteLine("初始化组件开始");
            await next.Invoke(environment);
            Console.WriteLine("管道执行完毕");
        }
    }

     第四种写法我们可以集成Microsoft.Owin库中的OwinMiddleware基类来实现中间件类。它提供了强类型访问IOwincontext。

    public class LoggingMiddleware : OwinMiddleware
    {
        public LoggerMiddleware(OwinMiddleware next)
            : base(next)
        {
        }
    
        public async override Task Invoke(IOwinContext context)
        {
            Console.WriteLine("初始化组件开始");
            await Next.Invoke(context);
            Console.WriteLine("管道执行完毕");
        }
    }

    以上几种写法实现都干了一样的事情,其实更多复杂的中间件定义可以参考下Microsoft.AspNet.Diagnostics下的几种中间件实现方式,比入WelcomePageMiddleware.cs,就是我们在app中使用UserWelcomPage()方法注册的中间件。

    劳神费力的,点歌赞打赏打赏
  • 相关阅读:
    [转]多线程更新Processbar
    不能因技术后天的死 而迷茫了今天的“学” 生
    NSIS 安装包制作相关
    [转]yslow 评分标准
    c# winform 打印 窗体 及 窗体控件内容 的 初级尝试
    严重认知自身成长 与诸博友共勉
    [转]NSIS 的 Modern UI 教程
    爱的幸福
    遍历WinForm窗体 根据语言类型设置其控件Text显示
    多借鉴 多思考
  • 原文地址:https://www.cnblogs.com/zfcflower/p/4280830.html
Copyright © 2020-2023  润新知