ESFramework介绍之(26)-- 支持复杂插件(InnerDealer 和 InnerDispatcher)

简介: (本文内容适合于 ESFramework V0.2+)    通常,最单纯的情况是一个插件对应某一特定类型的功能请求,但是,在有的应用中也会出现这样的情况,有多种类型的功能请求相互关联、并且可能交叉,如果是这样,对应每种类型的请求都开发一个插件可能会非常困难,因为这可能会牵涉到插件之间的相互引用/访问,这违背了插件的“自治”性。
    (本文内容适合于 ESFramework V0.2+)
    通常,最单纯的情况是一个插件对应某一特定类型的功能请求,但是,在有的应用中也会出现这样的情况,有多种类型的功能请求相互关联、并且可能交叉,如果是这样,对应每种类型的请求都开发一个插件可能会非常困难,因为这可能会牵涉到插件之间的相互引用/访问,这违背了插件的“自治”性。最好的办法还是将它们放在一个插件中,通过ServiceItemIndex(你一定还记得消息头定义中除了ServiceKey外还有个ServiceItemIndex属性)来区分相互关联的各种请求类型。
    当涉及的请求类型非常多时,我们的插件会变得非常复杂,通常的解决方案是在插件内部构建“内部处理器”InnerDealer,然后将ServiceItemIndex映射到对应的“内部处理器”上,这个映射可以由“内部分派器”InnerDispatcher完成。需要注意的是,并不需要为每个ServiceItemIndex都构建一个“内部处理器”,一个“内部处理器”可能能处理多个ServiceItemIndex的请求类型。下面我们重点关注“内部处理器”和“内部分派器”的实现。
   
    内部分配器接口IInnerDispatcher定义如下:
    public   interface  IInnerDispatcher
    {        
        
string  AddinAssemblyName{ set  ;}  // 本插件程序集的名称

        
void  Initialize() ;
        IInnerDealer GetDealer(
int  serviceIndex) ;
    }

     最主要是GetDealer()方法的实现,它根据消息头中的 ServiceItemIndex返回对应的内部处理器,你也许想到了,这可以通过Switch分支将serviceItemIndex映射到对应的内部处理器,然后这种集中管理的方式不是很方便,比如,当增加/删除一个内部处理器时,就要在这里增加/删除对应的分支语句。更好的办法是,让内部处理器能自己暴露它能处理的ServiceItemIndex的集合,这样,在运行时,可以通过反射动态的构建Mapping表,从而就避开了Switch语句及其引入的繁琐。
    内部处理器接口定义如下,它通过ServiceIndexCollection属性暴露了它能处理的ServiceItemIndex集合。
    public   interface  IInnerDealer
    {
        
int [] ServiceIndexCollection{ get  ;}

        NetMessage DealRequest(NetMessage reqMsg) ;
    }
    
    现在,我们可以实现 IInnerDispatcher的Initialize方法来动态构建Mapping表了:
        private   void  Initialize()
        {
            Assembly[] asses 
=  AppDomain.CurrentDomain.GetAssemblies();
            Type supType 
=   typeof (IInnerDealer)  ;

            
foreach  (Assembly ass  in  asses)
            {
                
string [] names  =  ass.FullName.Split( ' , ' ) ;
                
if (names[ 0 ].Trim()  ==   this .addinAssemblyName)
                {
                    
foreach (Type t  in  ass.GetTypes())
                    {
                        
if (supType.IsAssignableFrom(t)  &&  ( ! t.IsAbstract)  &&  ( !  t.IsInterface) )
                        {
                            IInnerDealer dealer 
=  (IInnerDealer)Activator.CreateInstance(t) ;
                            
if (dealer.ServiceIndexCollection  !=   null )
                            {
                                
foreach ( int  serKey  in  dealer.ServiceIndexCollection)
                                {
                                    
this .htDealer.Add(serKey ,dealer) ;
                                }
                            }
                        }
                    }

                    
break  ;
                }
            }
        }

    可以在IAddin.OnLoading方法中调用InnerDispatcher的Initialize方法进行初始化。

    IInnerDispatcher的GetDealer方法就显而易见了:
        public  IInnerDealer GetDealer( int  serviceIndex)
        {
            
return  (IInnerDealer) this .htDealer[serviceIndex] ;
        }

     功能插件的DealRequestMessage就变得相当简单:
        public  ESFramework.Network.NetMessage DealRequestMessage(ESFramework.Network.NetMessage reqMsg)
        {        
            IInnerDealer dealer 
=   this .dispatcher.GetDealer(reqMsg.Header.ServiceItemIndex) ;
            
if (dealer  ==   null )
            {
                
return   null  ;
            }

            
return  dealer.DealRequest(reqMsg) ;
        }
    
     插件中接下来需要做的工作就是实现你需要的IInnerDealer,实现的内部处理器不需要进行注册,它会在初始化插件时动态创建并被加入到Mapping表。需要注意的是,内部处理器的实现必须有一个无参的构造函数,否则,反射创建处理器实例将会抛出异常。
   

上一篇文章:ESFramework介绍之(25)-- 在插件中使用NHibernate

转到  :ESFramework 可复用的通信框架(序) 
目录
相关文章
|
传感器 监控 安全
|
开发框架 供应链 JavaScript
齐套检查与分配在生产计划中的实现
最近一段时间看到很多关于生产计划中,作齐套检查与分析讨论,正好我们的易排1.5版添加了类似功能。本文结合易排平台上相应的功能与特征,介绍一下我们在这方面的些许研究结论与看法。
391 0
|
10月前
|
人工智能 运维 安全
阿里云先知安全沙龙(上海站) ——终端安全对抗及防护
终端安全现状面临多重挑战,包括传统签名技术失效、新型无文件攻击频发、专业人才匮乏、分支机构安全管理不足等。企业终端覆盖不全、日志缺失、策略更新依赖厂商,导致运营排查困难。钓鱼攻击手法愈发精细,静态和动态对抗加剧,攻击者利用正常权限入侵,窃取凭据。Web3技术发展使加密货币成为新目标,职业黑客盯上个人钱包和交易公司。防护升级需涵盖预防、检测、响应和运营四个阶段,借助AI和威胁情报降低告警量,提升整体安全水平。
|
XML Web App开发 开发框架
回声嘹亮 之 Go 的 Echo 框架 —— 上手初体验
Echo 是众多 Go Web 框架的一个,根据官网介绍,它有着高性能、可扩展性、极简的特点。
回声嘹亮 之 Go 的 Echo 框架 —— 上手初体验
|
存储 Android开发
方法:一键把一堆手机号码一次性快速导入手机通讯录
手机是人们日常沟通常用的工具,所以自然就要用到手机里面的通讯录联系。因此我们常要把别人的号码存入到手机通讯录里面,如果只是存五个十个那就动动手指就可以了。但是如果你想存把一个电脑excel表格里面的几百个、几千个、几万个等数量级别的联系人一键导入手机通讯录,显然手动一个个来存入是不现实的。我这里演示,通过借助网上常见的便捷工具软件,金芝号码提取导入助手,代替你手动工作来快速完成这个工作,如何一键把一堆手机号码一次性快速导入手机通讯录,省事省时省力。下面做个操作过程的图文讲解。
4649 0
方法:一键把一堆手机号码一次性快速导入手机通讯录
|
传感器 人工智能 达摩院
“行”稳致远,国网智能与阿里云联手解决电力机器人行业难题
9月6日,国网智能宣布与阿里云在导航系统领域展开发展合作,首轮聚焦在轮式巡检机器人产品。
635 0
“行”稳致远,国网智能与阿里云联手解决电力机器人行业难题
|
Shell 开发工具 git
关于Hexo配置使用Next主题
之前写了个如何搭建Hexo的博客,后来想了想,既然写了就写到底吧,我自己用的是next这款主题,所以就说一下有关next的配置问题。并且,使用这个主题的过程中,我真的踩了不少的水坑!
什么是系统镜像文件?
什么是系统镜像文件?
1134 0
|
JSON 开发者 数据格式
微信服务号通过客服接口主动给普通微信号推送消息
当用户主动发消息给公众号的时候(包括发送信息、点击自定义菜单、订阅事件、扫描二维码事件、支付成功事件、用户维权),微信将会把消息数据推送给开发者,开发者在一段时间内(目前修改为48小时)可以调用客服消息接口,通过POST一个JSON数据包来发送消息给普通用户,在48小时内不限制发送次数。此接口主要用于客服等有人工消息处理环节的功能,方便开发者为用户提供更加优质的服务。
713 0
微信服务号通过客服接口主动给普通微信号推送消息
|
安全 开发者 云栖大会
阿里云代码管理平台云效Codeup亮相,为企业代码安全护航
云效Codeup是一款企业级代码管理产品,提供代码托管、代码评审、代码扫描、质量检测等功能,通过智能算法保护企业资产安全、稳定、高效交付。
9869 3
阿里云代码管理平台云效Codeup亮相,为企业代码安全护航