WebApi 插件式构建方案

时间:2021-12-18 13:52:50

WebApi 插件式构建方案

WebApi 插件式构建方案

公司要推行服务化,不可能都整合在一个解决方案内,因而想到了插件式的构建方案。最终定型选择基于 WebApi 构建服务化,之所以不使用 WCF 是因为不符合 RESTful 风格,并且对 OData 开源查询协议支持不是太好。

插件化构建的两种思路

  1. 不进行二次开发,直接把编译完成的程序集放到 bin 目录即可。
  2. 针对程序集寻址做扩展,把插件程序集放到 bin 的二级目录。

在这里,我对两者的优缺点进行一下分析:

  • 第一种方案:如果是临时方案我没有意见,毕竟是过渡用的,业务为重嘛。但是,作为万人敬仰的程序员,你他娘的也太懒了吧!那么多程序集放在一起,万一堆太多堆太久生蛆了肿么办?万一哪家小朋友不听话,把自己埋了肿么办?
  • 第二种方案:嗯,还得开发,而且弄不好还会把项目搞砸!后果很严重,领导很生气!肿么办?无奈 + 无解。。。

其实不用那么麻烦,用别人开发的一套成熟的东西就好办了。没有?好,坐下来,听我慢慢说。

WebApi 启动流程简介

任何基于 Http 的服务端程序,启动管道和请求响应管道指定是跑不了的。

  • 启动管道是服务自我配置的过程:这个时候 XML 配置和一些默认的约定就起作用了,比如 IOC 容器 Unity 启动时会从 unity.config 文件中读取映射配置,WebApi 框架缺省情况下会寻找从 ApiController 继承并且类名称结尾是 Controller 的类作为控制器。
  • 请求响应管道是服务器接到客户端请求后的处理流程:可以想象一下我们公司里的审批流,你要请假了,必须得小组长先批准,然后总监批准,接着人力审核,财务扣钱等等。在这里,一般会首先进行认证,授权和附加信息获取等流程,最后才会交给咱程序员写的逻辑去处理。

注:对于自承载的服务,也会有一个类似的流程。

流程一:获取程序集列表

挂载在 IIS 上时,会从 BuildManager 中获取程序集列表:这个列表是经过 ASP.NET 程序底层优化过的,能够获取所有的程序集信息。自承载时,只是简单粗暴地调用 Assembly 类的静态方法,估计会有一些问题,我没试过,这里不做讨论。考虑到绝大多数人还是使用 IIS 挂载的,说太详细没什么意义,我也没那个精力。

.Net 4.0 时代,ASP.NET 程序启动时,可以给程序集加上一个 Attribute(PreApplicationStartMethod),可以添加一些启动后不能变更的工作。这里我们要做的工作,就是把那些不在bin 根目录的程序集加载进去,通过 AddReferencedAssembly 静态方法添加即可。

注意:

  • 不要加载一个程序集的不同版本,这会对程序的运行产生不可预知的影响。
  • ASP.NET 的某些变量还没初始化,你的某些想法不会成立。

这里,我在加载了程序集的基础上,又公开了一些模块的元数据信息:

  • 插件的初始配置:插件名称、路径、启动顺序、可用性、插件可见性、数据库连接字符串。
  • 插件运行需要加载的程序集列表。

这些信息使得我在服务运行后,有了较大的定制空间。比如后面根据模块名称产生模块前缀 RESTful 服务;还有在另外的管理网站,统一管理服务的帮助系统等,源数据都是以其为依据的。

注:插件初始配置中,可用性决定了这个插件是否加载,这是总开关。

流程二:IOC 容器初始化

现代的网站,很难想象如果没有 IOC ,程序的复杂性会提升多少。所以我把 IOC 的初始化提升到最重要的位置。但是考虑到 IOC 容器不同人会有不同的选择,我这里只依照微软 Unity为蓝本做讲解。至于各个插件的使用上,统一采用 CommonServiceLocator 做 IOC 容器接口。

这里我解释下为什么使用 CommonServiceLocator 做使用的接口方案:

  • 接口稳定:君不见微软这么多年来,从来没更新过这货吗?
  • 适配器丰富:可以这么说,.Net 世界的 IOC 容器,几乎都有针对的适配器。所以说,不用考虑将来更换 IOC 容器实现时,各个插件的更新问题。这根本就不是事!
  • 公司一直在在用 Unity ,而且还专门做了接口实现,没得选没的说,不解释。

根据流程一提供的插件路径,约定 Configuration\unity.config 为存储接口映射的地方,在程序启动时依据插件启动顺序,逐个加载映射信息。

这一步完成后,就可以直接通过容器获取接口的实例了,很好的隔离了契约和实现,同时也让我们的程序趋于简单化,不用再用复杂的抽象工厂了。话说使用抽象工厂的配置也不比配置 IOC 容易,还都是私有的配置,一个个实现都不同,新人刚进入环境就是一头雾水。

流程三:集成加载数据库连接字符串

每个插件一般都会有自己的数据库访问功能,因为是插件化的方案,所以此时数据库连接字符串就很不好处理:生成后就不用再考虑连接字符串;插件自己放着就好,不用拷贝到指定的地方去。

很幸运,.Net 提供了一个叫做反射的东西,允许做一些工作后更新到 .Net 框架自带的连接字符串容器中,这样我们就可以在运行时不用管这个叫数据库连接字符串的东东了。唯一注意的一点就是:各个插件提供的数据库连接字符串名称不能有相同的。我相信这不是什么问题!

注:这个功能的实现依赖于流程一的插件初始配置,需要添加一个连接字符串所在文件的绝对路径的东东,以便于让系统指导从哪里获取这些连接字符串。每个模块都要配置一个,当然不用数据库操作的模块可以忽略。

流程四:重写的控制器获取工厂

缺省的控制器获取工厂,只会根据约定产生诸如 {controller}/{action}/{id} 这类的地址,那要我们插件如何是好?万一两家写的地址一样呢?小朋友会不会找不到家了呢?在前面加上{module} 可好?

好吧,我们假设方案是可行的,我们注册 {module}/{controller}/{action}/{id} 这样的路由,那就需要能解析这个路由的工厂才行啊,不然我们得不到控制器,谈何执行?

没什么可说的了,实现接口就好了,参考缺省实现,我们只需要把查找的 Key 加上模块名字就好了。

流程五:没什么可说的了

运行你的 WebApi 服务吧,网站不用引用你控制器项目,需要的时候把生成好的程序集放到 IIS 网站下你的目录就好了。这里推荐放在 bin 目录下面,好处是在你更新 bin 下面的文件时,IIS 会重新启动这个网站。

 
 
标签: WebApi插件分析架构

WebApi 插件式构建方案的更多相关文章

  1. WebApi 插件式构建方案:重写的控制器获取工厂

    body { border: 1px solid #ddd; outline: 1300px solid #fff; margin: 16px auto; } body .markdown-body ...

  2. WebApi 插件式构建方案:IOC 容器初始化

    body { border: 1px solid #ddd; outline: 1300px solid #fff; margin: 16px auto; } body .markdown-body ...

  3. WebApi 插件式构建方案:集成加载数据库连接字符串

    body { border: 1px solid #ddd; outline: 1300px solid #fff; margin: 16px auto; } body .markdown-body ...

  4. WebApi 插件式构建方案:发现并加载程序集

    插件式的 WebApi 开发,首要面对的问题就是程序集的发现.因为开发的过程中,都是在各自的解决方案下进行开发,部署后是分模块放在一个整体的的运行时网站下. 约定 这里我根据上一节的设定,把插件打包完 ...

  5. 零基础ASP.NET Core MVC插件式开发

    零基础ASP.NET Core MVC插件式开发 一个项目随着业务模块的不断增加,系统会越来越庞大.如果参与开发的人员越多,管理起来也难度也很大.面对这样的情况,首先想到的是模块化插件式开发,根据业务 ...

  6. asp.net webapi 自托管插件式服务(转)

    asp.net webapi 自托管插件式服务   webapi问世已久,稀里糊涂的人哪它都当mvc来使,毕竟已mvc使用级别的经验就可以应对webapi. webapi和mvc在asp.net5时代 ...

  7. asp.net webapi 自托管插件式服务

    webapi问世已久,稀里糊涂的人哪它都当mvc来使,毕竟已mvc使用级别的经验就可以应对webapi. webapi和mvc在asp.net5时代合体了,这告诉我们,其实 它俩还是有区别的,要不现在 ...

  8. 使用 SailingEase WinForm 框架构建复合式应用程序(插件式应用程序)

    对于一些较小的项目,具备一定经验的开发人员应该能够设计和构建出便于进行维护和扩展的应用程序.但是,随着功能模块数量(以及开发维护这些部件的人员)的不断增加,对项目实施控制的难度开始呈指数级增长. Sa ...

  9. 构建高性能插件式Web框架

    基于MVC插件模式构建支持数据库集群.数据实时同步.数据发布与订阅的Web框架系统.如下图: 1.基于插件式开发 采用插件模式开发的优点是使得系统框架和业务模式有效地进行分离,系统更新也比较简单,只需 ...

随机推荐

  1. 如果简单的记录,就可以为这个世界创造更多的财富,那么还有什么理由不去写博客呢? — 读<<黑客与画家>> 有感

    上一次博文发文时间是2016.1.15,7个月已经过去了.最近读了一本<>的书,对我触动挺大的!里面有关于技术趋势的探讨,也有关于人生和财富的思考! 开始更新iOS122的文章的初衷是,聚 ...

  2. &lt&semi;读书笔记&gt&semi;软件调试之道 :实证方法

    有效调试不仅仅是排除缺陷,其包含如下几个步骤 弄明白软件为何运行错误 修复这个问题 避免破坏其它部分 保持或者提高代码的总体质量 确保同样的问题不在其它地方发生,也不会再次发生 构建实验.观察结果 依 ...

  3. javascript 字符串和json的互转

    FROM:http://www.cnblogs.com/mizzle/archive/2012/02/10/2345891.html 在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操 ...

  4. hdoj1325 Is It A Tree&quest;

    Is It A Tree?题目链接 题意: 多组测试数据, 每组数据有多个数对, 表示一条有向边(即第一个数是第二个数的父节点), 以 0,0 为一组测试数据结束标志.当输入-1,-1时测试结束. 从 ...

  5. input事件以及中文输入法的处理

    在项目的开发过程中,相信大家都处理过监听用户输入的事情,一般我们会用到onkeyup.onkeydown.onkeypress.onchange.oninput事件,虽然都很熟悉了,但是还是有必要巩固 ...

  6. SpringMVC详解

    来源:Sunnier(http://www.admin10000.com/document/6436.html) 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入Spr ...

  7. mac 下SonarQube 安装与使用

    参考文件:https://www.jianshu.com/p/aa863cf30406 https://www.jianshu.com/p/b41262fca5b8 jenkins 集成Sonar: ...

  8. 基于WebGL架构的3D可视化平台—新风系统演示

    新风系统是根据在密闭的室内一侧用专用设备向室内送新风,再从另一侧由专用设备向室外排出,在室内会形成“新风流动场”,从而满足室内新风换气的需要.实施方案是:采用高风压.大流量风机.依靠机械强力由一侧向室 ...

  9. element

    <el-table-column label="地址" prop="address"> <template slot-scope=" ...

  10. (纪录片)鸟瞰中国 China from Above

    简介: 类型: 纪录片官方网站: natgeotv.com/uk/china-from-above制片国家/地区: 美国语言: 英语集数: 2单集片长: 44分钟IMDb链接: tt4872012 主 ...