定义

Middleware直译叫中间件,目前在百度上很难找到一个简单明了的含义解释,.Net下以前也比较难以看到它的身影,但在Microsoft.Owin里,多个地方都看到MiddleWare,我近来在尝试理解Middleware,并在实际中模仿应用,本文章将我的个人理解和大家分享一下。

Middleware的抽象

Microsoft.Owin的Middleware

public abstract class OwinMiddleware
{
protected OwinMiddleware(OwinMiddleware next); protected OwinMiddleware Next { get; set; } public abstract Task Invoke(IOwinContext context);
}

微软把Middleware定义在抽象类,除了Invoke的中间件执行入口,还有一个Next的中间件属性,两者都是非常抽象。Invoke正是本中间件的处理逻辑,参数IOwinContext包含问题试卷和答题卡,Next表示下一个中间件,如果本中间件不想解决此问题,那么就让Next来解决这个问题,以此类推。提问题的人不用关注是谁回答了问题,他只关注答案了够了。

简单的Middleware接口

如果我们把中间件定义为接口,那么一个简单的中间件接口可以如下:

public interface IMiddleware
{
IMiddleware Next { set; }
Answer GetAnswer(Question question);
}

当然,在一些实际项目中,中间件的抽象程度不一样,所以中间件的执行方法是根据实际需要作合理的设计,但Next一般不会有变化,它都是代表下一个中间件。

Middleware和插件的区别

插件是应用程序的功能扩展,它可以只关注自身的功能的实现,它可能不是带问题的,但各插件的执行接口是一样的,最简单的插件接口可以如下:

public interface IPlug
{
// 加载执行插件
void Init();
}

Middleware是问题解决单元抽象,它往往是由多个单元同时协同工作,各单元虽然没有直接关系,但Next属性还是得到了下个中间件的实例,提供给本中间件来传递。Middlware随着数量的增多,解决的问题各类也可以越多,和插件越多功能越丰富有相似。

Middleware的使用场景

我曾经写过《.Net下一个类型转换神器》,近期在代码重构,发现这玩意很适合使用中间件来实现。在类型转换中,调用者想要的是这种:

/// <summary>
/// 将value转换为目标类型
/// </summary>
/// <param name="value">要转换的值</param>
/// <param name="targetType">转换的目标类型</param>
/// <returns></returns>
object Convert(object value, Type targetType);

value和targetType千变万化,一口可吃不完,本着单一职责原则,我们应该要写很多转换单元,每个单元只负责一种类型转换,转换器由N多个转换单元组成,如果转换单元是中间件,抽象的中间件接口应该如下:

    /// <summary>
/// 定义类型转换单元的接口
/// </summary>
public interface IConvertMiddleware
{
/// <summary>
/// 设置下一个转换单元
/// </summary>
IConvertMiddleware Next { set; } /// <summary>
/// 将value转换为目标类型
/// </summary>
/// <param name="上下文">context</param>
/// <returns></returns>
object Convert(ConvertContext context);
}

实际当中,我们可能未必需要这么抽象,我的实际接口是

    /// <summary>
/// 定义类型转换单元的接口
/// </summary>
public interface IConvert
{
/// <summary>
/// 设置转换器
/// </summary>
Converter Converter { set; } /// <summary>
/// 设置下一个转换单元
/// </summary>
IConvert NextConvert { set; } /// <summary>
/// 将value转换为目标类型
/// </summary>
/// <param name="value">要转换的值</param>
/// <param name="targetType">转换的目标类型</param>
/// <returns></returns>
object Convert(object value, Type targetType);
}

然后,我们来一个一个地来实现转换单元:

某个单元的实现如下:

    /// <summary>
/// 表示不作转换的转换单元
/// </summary>
public class NoConvert : IConvert
{
/// <summary>
/// 转换器实例
/// </summary>
public Converter Converter { get; set; } /// <summary>
/// 下一个转换单元
/// </summary>
public IConvert NextConvert { get; set; } /// <summary>
/// 将value转换为目标类型
/// </summary>
/// <param name="value">要转换的值</param>
/// <param name="targetType">转换的目标类型</param>
/// <returns></returns>
public object Convert(object value, Type targetType)
{
if (targetType == typeof(object))
{
return value;
} if (value != null && targetType == value.GetType())
{
return value;
} return this.NextConvert.Convert(value, targetType);
}
}

NoConvert

更广泛的Middleware

我近来在开发开源项目《NetworkSocket》,自从看到Microsoft.Owin之后的中间件之后,觉得Middleware可以在很多领域中使用,现在这个项目里的协议解析实现者都已经完全由中间件来开发,功能越来丰富,但复杂度感觉没有增大。看看下面代码,你应该能感觉到Middleware的甜味。

var listener = new TcpListener();
listener.Use<HttpMiddleware>();
listener.Use<JsonWebSocketMiddleware>();
listener.Use<FastMiddleware>();
listener.Start();

Middleware的艺术的更多相关文章

  1. redux深入理解之中间件(middleware)

    理解reduce函数 reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值. arr.reduce([callback, initi ...

  2. 读书笔记:JavaScript DOM 编程艺术(第二版)

    读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...

  3. 有趣的 CSS 像素艺术

    原文地址:https://css-tricks.com/fun-times-css-pixel-art/#article-header-id-4 译者:nzbin 友情提示:由于国内网络的原因,Cod ...

  4. 你真的会玩SQL吗?透视转换的艺术

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  5. 用Middleware给ASP.NET Core Web API添加自己的授权验证

    Web API,是一个能让前后端分离.解放前后端生产力的好东西.不过大部分公司应该都没能做到完全的前后端分离.API的实现方式有很 多,可以用ASP.NET Core.也可以用ASP.NET Web ...

  6. [转]Writing Custom Middleware in ASP.NET Core 1.0

    本文转自:https://www.exceptionnotfound.net/writing-custom-middleware-in-asp-net-core-1-0/ One of the new ...

  7. [转]用Middleware给ASP.NET Core Web API添加自己的授权验证

    本文转自:http://www.cnblogs.com/catcher1994/p/6021046.html Web API,是一个能让前后端分离.解放前后端生产力的好东西.不过大部分公司应该都没能做 ...

  8. [译]Writing Custom Middleware in ASP.NET Core 1.0

    原文: https://www.exceptionnotfound.net/writing-custom-middleware-in-asp-net-core-1-0/ Middleware是ASP. ...

  9. 解读ASP.NET 5 & MVC6系列(6):Middleware详解

    在第1章项目结构分析中,我们提到Startup.cs作为整个程序的入口点,等同于传统的Global.asax文件,即:用于初始化系统级的信息(例如,MVC中的路由配置).本章我们就来一一分析,在这里如 ...

随机推荐

  1. IIS安装和使用(Windows Server 2003)

    1.安装IIS ①将系统盘插入光驱 ②进入:控制面板--添加/删除Windows组件--选择“应用程序服务器”--点击“详细信息” ③选择:ASP.NET和Internet信息服务(IIS),点击“确 ...

  2. InnoDB源码分析--缓冲池(二)

    转载请附原文链接:http://www.cnblogs.com/wingsless/p/5578727.html 上一篇中我简单的分析了一下InnoDB缓冲池LRU算法的相关源码,其实说不上是分析,应 ...

  3. FFMPEG ./configure 参数及意义

    FFMPEG版本:2.6.2,编译环境:ubuntu 14.4. 不同版本的FFMPEG参数可能不同,可在FFMPEG目录下使用以下命令查看 ./configure --help --help pri ...

  4. 命令行选项解析函数(C语言):getopt()和getopt_long()

    命令行选项解析函数(C语言):getopt()和getopt_long() 上午在看源码项目webbench时,刚开始就被一个似乎挺陌生函数getopt_long()给卡住了,说实话这函数没怎么见过, ...

  5. PCIe 32GT/s 含义

    如下: Jul 26 03:42:53 kernel: ixgbe 0000:01:00.1: PCI Express bandwidth of 32GT/s available Jul 26 03: ...

  6. hadoop2.6---常用命令

    为了方便操作,可以把hadoop加入环境变量 修改,vi ~/.bashrc export HADOOP_PREFIX=/app/programs/hadoop- export HADOOP_MAPR ...

  7. spring注入静态成员变量提示invalid setter method

    果然还是不够细心啊,被坑一晚上.. 一个极其简单的小程序,但是需要通过xml文件配置注入一个值,唯一的特别是要注入的属性是类中的静态成员变量.. 如下,然后自动生成get和set方法..坑就从此开始了 ...

  8. (一)半小时开发一个APP

    [前言] HPP是什么? HybirdApp的简称,详细介绍参见:HPP--让所有中小企业拥有自己的APP 说白了就是用html+css+js开发app,包括ios和android版本. HBuild ...

  9. 给textarea添加背景图

    给textarea添加背景图用的好也很有意思哦. <style type="text/css"> textarea{ background: url(img/carto ...

  10. [转]菜鸟程序员之Asp.net MVC Session过期异常的处理

    本文转自:http://www.cnblogs.com/JustRun1983/p/3377652.html 小赵是刚毕业的计算机专业方面的大学生,4年的大学时间里面,他读过了很多编程方面的数据,也动 ...