1 如何采用IoC实现对应用程序的流程控制-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何采用IoC实现对应用程序的流程控制

454398 来源:博客园 作者:蒋金楠 2020-10-29 11:21 次阅读

我之前写过一系列关于.NET Core依赖注入的文章,由于.NET Core依赖注入框架的实现原理发生了很大的改变,加上我对包括IoC和DI这些理论层面的东西又有了一些新的理解。

软件设计中由一些所谓的理念都没有一个明确的定义,比如之前流行的SOA和现在炒的火热的微服务(Micro Service)和无服务器(Serverless),我们都不能通过一个明确的“内涵”给它们一个准确地定义,只能从“外延”上描述这些架构设计应该具有怎样的特性。正因为无法给出一个明确的界定,造成了人们针对同一个概念出现了很多不同的理解。针对IoC也是这种情况,所以本章所诉的仅仅代表作者的一家之言,读者朋友姑妄听之,仅作参考。

一、流程控制的反转

我听到很多人将IoC说成是一种“面向对象的设计模式”,但在我个人看来IoC不能算作 一种“设计模式”,其自身也与“面向对象”没有直接的关系。我觉得很多人之所以不能很准确地理解IoC源于他们忽略了一个最根本的东西,那就是IoC这个短语,也就是他们之所以对IoC产生了诸多误解是因为他们忽略了IoC的定义。

IoC的全名Inverse of Control,翻译成中文就是“控制反转”或者“控制倒置”。控制反转也好,控制倒置也罢,它体现的意思是控制权的转移,即原来控制权在A手中,现在需要B来接管。那么具体对于软件设计来说,IoC所谓的控制权的转移具有怎样的体现呢?要回答这个问题,就需要先了解IoC的C(Control)究竟指的是怎样一种控制。对于我们所在的任何一件事,不论其大小,其实可以分解成相应的步骤,所以任何一件事都有其固有的流程,IoC涉及的所谓控制可以理解为“针对流程的控制”。

我们通过一个具体事例来说明传统的设计在采用了IoC之后针对流程的控制是如何实现反转的。比如说现在设计一个针对Web的MVC类库,我们不妨将其命名为MvcLib。简单起见,这个类库中只包含如下这个同名的静态类。

public static class MvcLib

{
    public static Task ListenAsync(Uri address);
    public static Task ReceiveAsync();
    public static Task CreateControllerAsync(Request request);
    public static Task ExecuteControllerAsync(Controller controller);
    public static Task RenderViewAsync(View view);
}

MvcLib提供了如上5个方法帮助我们完成整个HTTP请求流程中的5个核心任务。具体来说,ListenAsync方法启动一个监听器并将其绑定到指定的地址进行HTTP请求的监听,抵达的请求通过ReceiveAsync方法进行接收,我们将接收到的请求通过一个Request对象来表示。CreateControllerAsync方法根据接收到的请求解析并激活请求的目标Controller对象。ExecuteControllerAsync方法执行激活的Controller并返回一个表示视图的View对象。RenderViewAsync最终将View对象转换成HTML并作为当前请求响应的内容返回给请求的客户端。

现在我们在这个MvcLib的基础上创建一个真正的MVC应用,那么除了按照MvcLib的规范自定义具体的Controller和View之外,我们还需要自行控制从请求的监听与接收、Controller的激活与执行以及View的最终呈现在内的整个流程,这样一个执行流程反映在如下所示的代码中。

class Program

{
    static async Task Main()
    {
         Uri address = new Uri("http://0.0.0.0:8080/mvcapp");
         await MvcLib.ListenAsync(address);
         while (true)
        {
            var request = await MvcLib.ReceiveAsync();
            var controller = await MvcLib.CreateControllerAsync(request);
            var view = await MvcLib.ExecuteControllerAsync(controller);
            await MvcLib.RenderViewAsync(view);
        }
    }    
}

这个例子体现了如图1所示的流程控制方式(应用的代码完全采用异步的方式来处理请求,为了让流程图显得更加简单,我们在流程图中画成了同步的形式,读者不必纠结这个问题)。我们设计的类库(MvcLib)仅仅通过API的形式提供某种单一功能的实现,作为类库消费者的应用程序(App)则需要自行编排整个工作流程。如果从重用的角度来讲,这里被重用的仅限于实现某个环节单一功能的代码,编排整个工作流程的代码并没有得到重用。

图1 流程控制掌握在应用程序手中

但是当我们构建一个应用的时候,我们需要的不仅仅是一个能够提供单一API的类库,我们希望的理想形式是能够直接在一个现有的框架上构建我们的应用。类库(Library)和框架(Framework)的不同之处在于,前者往往只是提供实现某种单一功能的API,而后者则针对一个目标任务对这些单一功能进行编排形成一个完整的流程,这个流程在一个引擎的驱动下自动执行。

对于我们上面演示MvcLib来说,作为消费者的应用程序需要自行控制整个HTTP请求的处理流程,但这是实际上这是一个很“泛化”的工作流程,几乎所有的MVC应用均采用这样的流程监听、接收请求并最终对请求予以响应。如果我们将这个流程实现在一个MVC框架之中,由它构建的所有MVC应用就可以直接使用这个请求处理流程,而不需要自行重复实现它。

现在我们将MvcLib从类库改造成一个框架,并姑且将其称为MvcFrame。如图2所示,MvcFrame的核心是一个被称为MvcEngine的执行引擎,它驱动一个编排好的工作流对HTTP请求进行一致性处理。如果我们利用MvcFrame构建一个具体的MVC应用,除了根据我们的业务需求定义相应的Controller和View之外,我们只需要初始化这个引擎并直接启动它即可。如果你曾经开发过ASP.NET MVC应用,你会发现ASP.NET MVC就是这么一个框架。

图2 流程控制反转到框架手中

有了上面演示的这个例子作为铺垫,我们应该很容易理解IoC所谓的控制反转。总的来说,IoC是我们设计框架所采用的一种基本思想,所谓的控制反转就是将对应用流程的控制转移到框架中。拿上面这个例子来说,在传统面向类库编程的时代,针对HTTP请求处理的流程牢牢控制在应用程序手中。在引入框架之后,请求处理的控制权转移到了框架手上。

二、好莱坞法则

在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项目的完全控制,演员只能被动式的接受电影公司的工作,在需要的环节中,完成自己的演出。“不要给我们打电话,我们会给你打电话(don‘t call us, we‘ll call you)”这是著名的好莱坞法则( Hollywood Principle或者 Hollywood Low),IoC完美地体现了这一法则。

图3 好莱坞法则

在IoC的应用语境中,框架就像是掌握整个电影制片流程的电影公司,由于它是整个工作流程的实际控制者,所以只有它知道哪个环节需要哪些组件。应用程序就像是演员,它只需要按照框架定制的规则注册这些组件就可以了,因为框架会在适当的时机字典加载并执行注册的组件。

以熟悉的ASP.NET Core MVC或者ASP.NET MVC应用开发来说,我们只需要按照约定规则(比如目录结构和命名等)定义相应的Controller类型和View文件就可以了。当ASP.NET (Core )MVC框架在进行处理请求的过程中,它会根据解析生成的路由参数定义为对应的Controller类型,并按照预定义的规则找到我们定义的Controller,然后自动创建并执行它。如果定义在当前Action方法需要呈现一个View,框架自身会根据预定义的目录约定找到我们定义的View文件,并对它实施动态编译和执行。整个流程处处体现了“框架Call应用”的好莱坞法则。

总的来说,我们在一个框架的基础上进行应用开发,就相当于在一条调试好的流水线上生成某种商品,我们只需要在相应的环节准备对应的原材料,最终下线的就是我们希望得到的最终产品。IoC几乎是所有框架均具有的一个固有属性,从这个意义上讲,“IoC框架”的说法其实是错误的,世界上并没有什么IoC框架,或者说几乎所有的框架都是IoC框架。

三、流程定制

我们采用IoC实现了流程控制从应用程序向框架自身的反转,但是这个被反转的仅仅是一个泛化的流程,任何一个具体的应用都可能需要对组成该流程的某些环节进行定制。还是以我们的MVC框架来说,可能默认的请求处理流程只考虑到针对HTTP 1.1的支持,但是当我们在设计框架的时候应该提供相应的扩展点来支持HTTP 2。作为一个Web框架,用户认证功能是必备的,但是框架自身不能限制于某一种或者几种固定的认证方式,应该通过扩展的方式让用户可以自由地定制任意的认证模式。

我们可以说得更加宽泛点。如图4所示,我们将一个泛化的工作流程(A=>B=>C)被定义在框架之中,建立在该框架的两个应用需要对组成这个流程的某些环节进行定制。比如步骤A和C可以被App1重用,但是步骤B却需要被定制(B1),App2则重用步骤A和B,但是需要按照自己的方式处理步骤C。

图4 应用程序对流程的定制

IoC将对流程的控制从应用程序转移到框架之中,框架利用一个引擎驱动整个流程的执行,应用程序无需关心该工作流程的细节,它只需要启动这个引擎即可。但是这个引擎一旦被启动,框架就会完全按照预先编排好的流程进行工作,如果应用程序希望整个流程按照自己希望的方式被执行,针对流程的定制一般在发生在启动引擎之前。

一般来说,框架会以相应的形式提供一系列的扩展点,应用程序则通过定义扩展的方式实现对流程某个环节的定制。在引擎被启动之前,应用程序将所需的扩展注册到框架之中。一旦引擎被正常启动,这些注册的扩展会自动参与到整个流程的执行过程中。

综上所述,IoC一方面通过流程控制从应用程序向框架的反转实现了针对流程自身的重用,另一方面通过内置的扩展机制这个被重用的流程可能自由地被定制,这两个因素决定了框架自身的价值。重用让框架不仅仅是为应用程序提供实现单一功能的API,而是提供一整套可执行的解决方案,可定制则使我们可以为不同的应用程序对框架进行定制,这无疑让框架可以使用到更多的应用之中。
编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 无服务器
    +关注

    关注

    0

    文章

    16

    浏览量

    4066
收藏 人收藏

    评论

    相关推荐

    使用树莓派实现程控制的技巧

    树莓派是一款功能强大的微型计算机,其体积小巧、价格低廉,非常适合用于各种DIY项目。其中,远程控制是树莓派应用中非常受欢迎的一个领域。通过远程控制,我们可以随时随地访问和管理树莓派,实现数据监控
    的头像 发表于 11-11 11:37 431次阅读

    程控制温控器的应用

    连接到用户的智能手机或其他移动设备。用户可以通过专门的应用程序远程监控和调节家中的温度。这些温控器通常与家中的中央供暖和制冷系统相连,能够根据用户的设定自动调节室内温度。 远程控制温控器的优势 节能高效 :用户可以根
    的头像 发表于 11-06 13:47 312次阅读

    普通空开怎样远程控制断电

    程控制断电技术的应用场景非常广泛,包括但不限于: 智能家居系统 :用户可以通过手机应用或语音助手远程控制家中的电器,实现节能和便捷。 工业自动化 :在生产线上,远程控制断电可以快速
    的头像 发表于 10-17 14:02 525次阅读

    嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-shell脚本编写之流程控制

    1、条件语句shell语句的流程控制与C语言不一样,流程控制中不能为空。shell中if语法如下,其中confition表示条件判断式,command为程序段落。if else语法
    发表于 09-05 09:06

    所有的labview应用程序的三要素是什么

    的一种图形化编程语言,它广泛用于数据采集、仪器控制、自动化测试和过程控制等领域。LabVIEW应用程序通常由三个基本要素组成:前面板(Front Panel)、块图(Block Diagram)和图标
    的头像 发表于 09-04 16:08 334次阅读

    飞凌嵌入式ElfBoard ELF 1板卡-shell脚本编写之流程控制

    1、条件语句 shell语句的流程控制与C语言不一样,流程控制中不能为空。 shell中if语法如下,其中confition表示条件判断式,command为程序段落。 if else语法
    发表于 09-04 10:12

    android 远程控制如何实现

    在现代工作和生活中,远程控制安卓设备或使用安卓设备远程控制其他设备已成为常见需求。安卓远程控制允许IT管理员远程访问安卓设备。实施远程控制应用程序
    的头像 发表于 08-21 18:05 881次阅读
    android 远<b class='flag-5'>程控制</b>如何<b class='flag-5'>实现</b>

    什么是智慧运营中心IOC?功能有哪些?

    随着智能时代的到来,越来越多的行业管理者开始使用先进的运营管理中心,以前的已经不能够满足于需求了。那么,什么是智慧运营中心IOC?功能有哪些?想必很多人都还不太了解,今天古河云科技就来给大家聊一聊
    的头像 发表于 05-23 14:35 829次阅读
    什么是智慧运营中心<b class='flag-5'>IOC</b>?功能有哪些?

    什么是IOC?应该如何识别和响应?

    网络安全中的IOC是什么?IOC和IOA有什么区别?IOC有哪些类型?IOC的常见实例有哪些?IOC解决方案和工具近期,Wireshark大
    的头像 发表于 03-21 08:04 5058次阅读
    什么是<b class='flag-5'>IOC</b>?应该如何识别和响应?

    信捷plc远程控制怎么实现?如何远程修改程序?

    怎么实现?如何远程修改程序? 利用物通博联PLC远程模块将信捷PLC接入网络,实现与远程控制中心的无线连接,无需布线,工程师可以随时随地远程控制
    的头像 发表于 02-22 16:02 1363次阅读
    信捷plc远<b class='flag-5'>程控制</b>怎么<b class='flag-5'>实现</b>?如何远程修改<b class='flag-5'>程序</b>?

    闸门改造远程控制系统

    智能改造闸门主要是针对老式非智能闸门进行智能化改造,使其具备测控一体化闸门的功能要求,即实现可现场对闸门进行控制,也可远程控制闸门启闭,另外也可接入渠道水位、流量、视频等采集信息,通过闸控系统
    的头像 发表于 02-22 11:06 815次阅读
    闸门改造远<b class='flag-5'>程控制</b>系统

    示波器与示波器探头如何实现程控制及区分?

    示波器与示波器探头如何实现程控制及区分? 示波器是电子测试仪器中的一种,它主要用于显示和测量电信号的波形和电压。示波器探头则是示波器和要测量的电路之间的连接,用于将电路的电压信号传递给示波器进行
    的头像 发表于 01-19 16:16 783次阅读

    可编程控制器的组成 可编程控制器有哪些特点?

    可编程控制器(Programmable Logic Controller,PLC)是一种使用数字计算机技术和专用外设实现工业过程自动化控制的设备。它在工业生产中起到了非常重要的作用。本文将详细介绍
    的头像 发表于 01-18 11:18 1496次阅读

    PLC远程控制网关:实现智能化生产的关键

    近年来,随着工业自动化的快速发展,越来越多的企业开始采用PLC远程控制网关来实现生产过程的智能化管理。这种创新的技术不仅能够提高生产效率,还可以降低成本,并且为企业带来更多的商业机会。PLC远
    的头像 发表于 01-16 17:39 718次阅读
    PLC远<b class='flag-5'>程控制</b>网关:<b class='flag-5'>实现</b>智能化生产的关键

    mysql8.0流程控制介绍

      流程控制介绍 解决复杂问题不可能通过一个SQL语句完成,我们需要执行多个SQL操作。流程控制语句的作用就是控制存储过程中SQL语句的执行顺序,是我们完成复杂操作必不可少的一部分。只要是执行的
    的头像 发表于 01-13 10:36 673次阅读