OWIN 请求处理与中间件
OWIN 请求处理与中间件
OWIN 请求处理函数
在 OWIN 的最底层, 处理请求的函数定义的委托签名如下:
Func<IDictionary<string, object>, Task>
这个函数接受类型为 IDictionary<string, object>
的 OWIN 环境, 返回一个 Task
对象。
通常可以为这个函数起这样的别名:
using AppFunc = Func<
IDictionary<string, object>, // OWIN 环境
Task>; // 任务
于是,请求处理函数可以这样表示:
Func<AppFunc, Task>
OWIN 中间件 (Middleware)
中间件是 OWIN 中很重要的概念, 中间件介于 OWIN 服务器 与 OWIN 应用之间, 通过职责链模式处 理请求。
OWIN 为 Middleware 的注册提供了三个版本的重载函数, 可以分别适用于不同的场景:
public interface IAppBuilder {
IAppBuilder Use(object middleware, params object[] args);
}
public static class AppBuilderUseExtensions {
public static IAppBuilder Use<T>(
this IAppBuilder app,
params object[] args
);
public static IAppBuilder Use(
this IAppBuilder app,
Func<IOwinContext, Func<Task>, Task> handler
);
}
根据这三个方法, 添加 Middleware 有如下几种方式:
Lambda 表达式
使用 Lambda 表达式可以创建简单的或者用于诊断的中间件, 比如:
app.Use(async (context, next) => {
Console.WriteLine("Middleware with Lambda begin.");
await next();
Console.WriteLine("Middleware with Lambda end.");
});
当然, Middleware 执行时可以不必等待下一个处理程序结束而直接返回, 比如:
app.Use(async (context, next) => {
Console.WriteLine("Middleware with Lambda begin.");
return Task.FromResult(0);
});
Middleware 类型
创建自定义 Middleware 类型是最通用的方式, 只要遵守 OWIN 的约定即可:
- 构造函数的第一个参数必须是处理管线中的下一个处理函数;
- 必须有一个 Invoke 函数, 接受 OWIN 环境参数, 返回 Task;
示例代码如下:
using AppFunc = Func<IDictionary<string, object>, Task>;
public class LogMiddleware {
private readonly AppFunc next;
public LogMiddleware(AppFunc next) {
this.next = next;
}
public async Task Invoke(IDictionary<string, object> env) {
Console.WriteLine("LogMiddleware Start.");
await next(env);
Console.WriteLine("LogMiddleware End.");
}
}
使用上面的中间件的代码如下:
app.Use<LogMiddleware>(/* 构造函数其它参数 */);
在运行时, OWIN 通过反射调用 LogMiddleware 的构造函数创建实例并调用 Invoke 方法。
Middleware 实例
当然,还可以直接使用 Middleware 的实例, 这样很适用于有 IoC 容器的场景, 同样, 只要符合 OWIN 的约定即可:
- 必须有一个 Initialize 实例方法, 该方法接受的第一个参数必须是上面的
AppFunc
; - 必须有一个 Invoke 实例方法, 该方法接受 OWIN 环境参数, 返回
Task
;
示例代码如下:
using AppFunc = Func<IDictionary<string, object>, Task>;
public class InstanceMiddleware {
private AppFunc next;
public void Initialize(AppFunc next) {
this.next = next;
}
public async Task Invoke(IDictionary<string, object> env) {
Console.WriteLine("InstanceMiddleware Start.");
await next(env);
Console.WriteLine("InstanceMiddleware End.");
}
}
Middleware 实例可以这样使用:
var instance = new InstanceMiddleware();
/*
instance 后面可以添加 Initialize 方法的其它参数, 如果有 IoC 容器的话, 似乎就没什么
必要了
*/
app.Use(instance);
OwinMiddleware 子类
如果对上面的反射以及约定不感兴趣的话, 还可以使用 OwinMiddleware
基类, 该类型定义 如下:
public abstract class OwinMiddleware {
protected OwinMiddleware Next { get; set; }
protected OwinMiddleware(OwinMiddleware next) {
this.Next = next;
}
public abstract Task Invoke(IOwinContext context);
}
使用基类的话, 上面的 LogMiddleware 就要这样写了:
public class LogOwinMiddleware : OwinMiddleware {
public LogOwinMiddleware(OwinMiddleware next)
: base(next) {
}
public async override Task Invoke(IOwinContext context) {
Console.WriteLine("LogOwinMiddleware Start.");
await Next.Invoke(context);
Console.WriteLine("LogOwinMiddleware End.");
}
}
上面对 Middleware 的介绍比较全了, 如果要做 OWIN Middleware 开发的话, 可以从这几种方式 入手。
PS: 还有一种使用內联函数的方式, 也提一下, 但是个人不怎么推荐, 比如 Middleware 可以表示成:
Func<AppFunc // next process delegate,
AppFunc // this process delegate
>
使用起来是这样自的:
app.Use(new Func<AppFunc, AppFunc>(next => (async env => {
Console.WriteLine("Middleware with AppFunc begin.");
await next.Invoke(env);
Console.WriteLine("Middleware with AppFunc end.");
})));
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- pytorch加载自己的图像数据集实例
- python实现批量转换图片为黑白
- Keras构建神经网络踩坑(解决model.predict预测值全为0.0的问题)
- Python实现验证码识别
- 详解PHP神奇又有用的Trait
- laravel实现按时间日期进行分组统计方法示例
- Pytorch 使用CNN图像分类的实现
- PHP实现无限极分类的两种方式示例【递归和引用方式】
- 记录模型训练时loss值的变化情况
- phpstorm 配置xdebug的示例代码
- 利用Python实现Excel的文件间的数据匹配功能
- PHP设计模式之简单工厂和工厂模式实例分析
- PHP实现数据四舍五入的方法小结【4种方法】
- 如何在Windows中安装多个python解释器
- PHP设计模式之抽象工厂模式实例分析