Middleware的艺术

定义

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(1212);
时间: 2024-10-20 06:37:18

Middleware的艺术的相关文章

Middleware

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

在Laravel中使用Middleware进行身份验证

新建一个中间件: 方法写在handle中 判断用户是否登录而且是否是管理员,不是的话返回到主页 新建判断是否为管理员的方法 在kernel定义一个中间件,key是admin 注册群组路由:prefix是路由前缀,访问路由会自动在前面加上路由前缀:middleware是key值,会去验证中间件 1在数据库中是管理员 成功 附: 注册单个路由的中间件: Route::get('admin/profile', ['middleware' => 'auth', function () { // }]);

2017.4.7------软件测试的艺术+整理以前的摘记

2017.4.17 以下内容来自<软件测试的艺术> 第1页--20页.供自己学习使用.   第一章 软件测试:就是一个过程或一个系列过程,用来确认计算机代码完成了其应该完成的功能,不执行其不该有的操作. 第二章    测试人员需要有正确的态度.每当测试一个程序时,应当想到的是为程序增加一些价值.通过测试来增加程序的价值,是指测试提高了程序的可靠性或质量,提高程序可靠性,是指找出并最终修改了程序的错误. 1.有人把没发现错误的测试用例称为一次"成功的测试",而将发现了某个新错

Laravel 5.0 - Middleware (中间件)

图片:http://stackphp.com/ 如上图所示,中心的绿色区域是整个应用的核心区域. 所以,中间件就是一系列处理请求和响应的方式而不是你用程序逻辑的一部分. Laravel 中默认使用中间件处理请求中的加密解密,以及 Cookies 和 Sessions.你也可以自定义自己所需的中间件. 写中间件 artisan make:middleware MyMiddleware 执行上面的命令,生成中间件文件: <?php namespace App\Http\Middleware; use

解读微信质变、解读张小龙的七大价值观、解读领导艺术

微信张小龙简介: 伟大的.光荣的.正确的双料创始人.Foxmail创始人和微信创始人. 一般能成为"创始",那肯定其产品在一段时间广受大家欢迎和使用,并深入用户心灵,在同行业内起到标杆作用.三者去一不可,1)受欢 2)为用户着想 3)标杆. "创始"还不够,还得是人.一般像我这种货色天天弄篇水文,弄个电子读物,也只能自称"XX文章系列"撰写"者"."者"和"人"区别很大,往往后者能被后世

《计算机程序设计艺术》pdf

下载地址:网盘下载 内容简介 编辑 本书作者D. E. Knuth是在计算机学界十分著名的学者,在本领域享有很高权威和盛名,他的这部著作是无数计算机专业人员的学习教材和参考读物,也是许多专业研究工作者经常阅读的经典.本书已被翻译为几十种文字在世界各地出版,英文原版书在国外已经是第11次印刷. 该书1999年底被American Scientist列为20世纪最佳12部学术专著之一(与狄拉克的量子力学.爱因斯坦的相对论.曼德布罗特的分形论.鲍林的化学键.罗素和怀特海德的数学原理.冯诺意曼和摩根斯坦

沟通和编程一样,也是一门艺术系列2(沟通前应该有的心理准备)

生活.学习.工作离不开沟通.在眼下更加注重团队合作的时代,沟通显得更加重要,让沟通上升到艺术的层次.笔者在此分享一直以来所学到的关于沟通的心得.体会,希望对看到这篇文章的朋友有所帮助和启示. 1 沟通前的心理准备 1.1 开会谁先发言? 开会尽量不要先开口,先开口把底牌先凉,没保障,不开口也不行,认清形势,形势好的人.不急着开口,居高位的人,也不用急于开口,形势不好的人先开口. 1.2 营销的沟通 卖东西,卖的是价值,不能随便降价.嫌货就是买货人,不买不会挑毛病,顾客主动说明来意(大单生意),多

沟通和编程一样,也是一门艺术系列4(沟通的原则)

1 沟通原则 1.1 对待消息的原则 每一个人听到话之后要思考,话里面有没有他添油加醋的,有没有成见,有没有主观的部分,听到什么地步,加以调整才告诉别人(样例:报告上司下属的加薪要求.你下属对你讲话比較没保留.可是直接对上层领导会让三分). 当把消息告诉别人时,不要说出消息来源,不然自己难堪,并且连来源都没有了.也不要问别人消息的来源.一般不要问是谁说的. 1.2 与别人说话原则 多听.多想.多看.少说.沉默是金,站在对方的立场来讲,站在不讲的立场来讲.祸从口出. 别人找你商议不一定是来征求你意

Android开发艺术探索——第七章:Android动画深入分析

Android开发艺术探索--第七章:Android动画深入分析 Android的动画可以分成三种,view动画,帧动画,还有属性动画,其实帧动画也是属于view动画的一种,,只不过他和传统的平移之类的动画不太一样的是表现形式上有点不一样,view动画是通过对场景的不断图像交换而产生的动画效果,而帧动画就是播放一大段图片,很显然,图片多了会OOM,属性动画通过动态的改变对象的属性达到动画效果,也是api11的新特性,在低版本无法使用属性动画,但是我们依旧有一些兼容库,OK,我们还是继续来看下详细