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()方法注册的中间件。

时间: 2024-08-23 02:28:44

OWIN katana注册中间件的几种写法的相关文章

循环注册事件的几种写法

<body> <ul> <li>0</li> <li>1</li> <li>2</li> </ul> <script> var node = document.querySelectorAll('ul li') for(var i = 0;i<node.length;i++){ node[i].addEventListener('click',function(){ alert('

Android学习笔记(3)——按钮点击注册事件的四种写法

搬运自本人博客,xge技术博客 http://www.xgezhang.com/android_button_onclick_4_ways.html Android下,按钮点击事件是在开发过程中经常会写到的东西.这里总结一下常见的四种写法: 界面代码就是一个button控件: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <RelativeLayout xmlns:android="http://schemas.android.com/apk/re

Android点击事件的四种写法

Android点击事件的四种写法 一.Android点击事件的四种写法 1.点击事件的第一种写法 .  写一个内部类.实现点击事件的接口 bt.setOnClickListener(new MyButtonListener()); 2.点击事件的第二种写法,匿名内部类 bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { callPhone(); } }); 3.点击事件的第三种

谈谈垂直分割线的几种写法

谈谈分垂直分割线的几种写法,我们对这种分隔线不会陌生,在项目需求中会经常遇到,我们来看看 下边的几种写法, 方法一: <div> <a href="">注册</a>|<a href="">登录</a> </div> 直接在文字中间插入短线字符: 优点:简单.直接.高效. 缺点:可控性差: 方法二: HTML: <div> <a href="" class=&

用UseMiddleware扩展方法注册中间件类

用UseMiddleware扩展方法注册中间件类 .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除了直接用ApplicationBuilder的Use()方法注册中间件外,还可以使用ApplicationBuilder的扩展方法UseMiddleware()注册中间件.这种情况下可以注册类型,这个方法会通过反射解析这个类型,并把它包装成Func<

无废话Android之常见adb指令、电话拨号器、点击事件的4种写法、短信发送器、Android 中各种布局(1)

1.Android是什么 手机设备的软件栈,包括一个完整的操作系统.中间件.关键的应用程序,底层是linux内核,安全管理.内存管理.进程管理.电源管理.硬件驱动 2.Dalvik VM 和 JVM 的比较 3.常见adb指令 platform-tools/adb.exe adb.exe : android debug bridge android调试桥 adb devices:列出所以连接的设备 adb kill-server :杀死adb调试桥 adb start-server :启动adb

Android代码学习--点击事件的几种写法

由来:常规的写法参见<写一个apk>,每次点击按钮,按钮先查找文本框等元素,然后再操作,其实查找操作是很费时的操作,因此将该定义放到Activity的onCreate中:Oncreate只会执行一次,这样Activity一旦执行,就先创建好控件们了. 第二种方法:通过匿名内部类的方法:就是button.setOnClickListener(new OnClickListener(){ //实现OnClickListener接口 @Override public void onClick(Vie

Android开发系列之按钮事件的4种写法

经过前两篇blog的铺垫,我们今天热身一下,做个简单的例子. 目录结构还是引用上篇blog的截图. 具体实现代码: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 方法1.

安卓中关于点击响应事件的四种写法(电话拨号器)

安卓中点击响应事件主要是用button响应事件,关于响应事件的大概有四种写法 1,,创建一个内部类,定义点击事件 2,创建一个匿名内部类,直接实现接口 3,让activity实现点击事件的接口(用的最多常见的情况) 4,4,在布局文件里面绑定一个点击的方法 < Button android:onClick= "dailButtonClicked" ..... /> 本次过程的一些代码是基于简单的电话拨号器的实现的 public class MainActivity exte