ESFramework介绍之(9)-- 插件对(Addin Pai

系统 1605 0
使用 ESFramework 开发 C/S (通常为 4 层、 3 层也没问题)应用,当需要增加一项新的业务时,我们需要做的仅仅是开发两个插件,一个是服务端的业务功能插件(FunAddin),一个是客户端插件( PassiveAddin ),这两个插件合在一起称为 Addin Pair 。开发这两个插件,只需要关注于业务,而其它与业务无关的比如网络通信、加密、数据安全,都不用管。 ESFramework 很好的将这些关注点分离开来,使得写“业务”插件的程序员的工作变得非常单纯,在 ESFramework 介绍之( 8 )-- 客户端插件 IPassiveAddin 一文给出的一个开发服务端功能插件和客户端插件的示例中,大家应该已经体会到这点了。

正如 上文 结尾处提到,当增加一项新的业务,调试包含了这个新业务实现的插件对( AddinPair )时非常麻烦,因为在 ESFramework 4 层架构中,服务端功能插件加载于功能服务器( FS )上,客户端插件加载在客户端应用程序上,中间的通信还经过了应用服务器(AS)。这样就要将 AS FS Client 都启动起来,才能对插件 Pair 进行调试,并且在这样调试的过程中,很多其它的因素会分散我们的注意力,比如多线程的影响、消息 Hook 的影响等等,这使得调试 Addin Pair 并不轻松,正是由于这个原因,促使我开发一个插件调试框架来简化这个麻烦的过程。

我的想法是,在 VS.NET 调试模式中运行这个“插件调试框架”(一个 winForm 应用程序),加载要调试的 Addin Pair ,然后,启动 “业务操作窗体”显示出来,后续的交互将在两个插件之间直接进行通信,而 VS.NET 提供了我们跟踪到加载的插件的源码中的能力,这样就可以调试 Addin Pair 了。 “插件调试框架”应用程序的主界面如下:

ESFramework介绍之(9)-- 插件对(Addin Pair)调试“框架”

测试模式中的“异常(功能服务器掉线)”用于模拟找不到对应服务端功能插件的情况。

我们知道,客户插件( PassiveAddin )通过 IServerAgent 来发送请求获取回复,在客户端应用程序中, IServerAgent 是对底层 Tcp Udp 的封装。在“插件调试框架”我们提供一个 IServerAgent 的实现给要调试的 PassiveAddin 使用, ESFramework 给出的实现是 AddinBridge 类,它实现了 IServerAgent 接口,并且把 PassiveAddin 提交的请求直接提交给已加载的业务功能插件处理。 AddinBridge 实现如下:

AddinBridge
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> 1 /// <summary>
2 /// AddinBridge用于将服务端插件和对应的客户端插件桥接起来,进行调试。
3 /// zhuweisky
4 /// </summary>
5 public class AddinBridge:IServerAgent
6 {
7 public AddinBridge()
8 {
9 }
10
11 #region Property
12 #region FunAddinManagement
13 private IAddinManagementfunAddinManagement = null ;
14 public IAddinManagementFunAddinManagement
15 {
16 set
17 {
18 this .funAddinManagement = value;
19 }
20 }
21
22
23 #endregion
24
25 #region TestMode
26 private TestModetestMode = TestMode.Normal;
27 public TestModeTestMode
28 {
29 set
30 {
31 this .testMode = value;
32 }
33 }
34 #endregion
35
36 #endregion
37
38 #region IServerAgent成员
39 public NetMessageCommitRequest(MessagerequestMsg,DataPrioritydataPriority, bool checkRespond)
40 {
41 if ( this .testMode == ESFramework.Addins.TestMode.FSOffline)
42 {
43 requestMsg.Header.MessageBodyLength = 0 ;
44 requestMsg.Header.Result = ServiceResultType.ServiceIsNotExist;
45 return new NetMessage(requestMsg.Header, null );
46 }
47
48 foreach (IFunAddinfunAddin in this .funAddinManagement.AddinList)
49 {
50 if (funAddin.ServiceKey == requestMsg.Header.ServiceKey)
51 {
52 // 交给功能插件处理
53 return funAddin.DealRequestMessage(requestMsg.ToNetMessage());
54 }
55 }
56
57 requestMsg.Header.MessageBodyLength = 0 ;
58 requestMsg.Header.Result = ServiceResultType.ServiceIsNotExist;
59 return new NetMessage(requestMsg.Header, null );
60 }
61
62 public NetMessageCommitRequest(MessagerequestMsg,DataPrioritydataPriority, int expectResServiceKey)
63 {
64 return this .CommitRequest(requestMsg,dataPriority, true );
65 }
66
67 #endregion
68 }
69
70 /// <summary>
71 /// 调试模式
72 /// </summary>
73 public enum TestMode
74 {
75 Normal,FSOffline
76 }



AddinBridge
借助了 IAddinManagement (插件管理器)来管理已加载的业务功能插件。

有了
AddinBridge 的支持,“插件调试框架”的实现就非常容易了,我将上图主界面中的按钮点击事件源码列在下面:

private AddinBridgeserverAgent = new AddinBridge();
private IPassiveAddinpassiveAddin = null ;
按钮事件处理
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> 1 private void button_server_Click( object sender,System.EventArgse)
2 {
3 this .textBox_server.Text = FileHelper.GetFileToOpen( " 请选择服务端插件 " , " .dll " );
4 IAddinManagementaddinManager = new AddinManagement();
5 string msg = null ;
6 bool succeed = addinManager.LoadNewAddin( this .textBox_server.Text, out msg);
7 if ( ! succeed || (addinManager.AddinList.Count == 0 ))
8 {
9 MessageBox.Show(msg + " 请重新选择插件! " );
10 return ;
11 }
12
13 this .serverAgent.FunAddinManagement = addinManager;
14 }
15
16 private void button_passive_Click( object sender,System.EventArgse)
17 {
18 this .textBox_passive.Text = FileHelper.GetFileToOpen( " 请选择客户端插件 " , " .dll " );
19 IAddinManagementaddinManager = new AddinManagement();
20 string msg = null ;
21 bool succeed = addinManager.LoadNewAddin( this .textBox_passive.Text, out msg);
22 if ( ! succeed || (addinManager.AddinList.Count == 0 ))
23 {
24 MessageBox.Show(msg + " 请重新选择插件! " );
25 return ;
26 }
27
28 this .passiveAddin = (IPassiveAddin)addinManager.AddinList[ 0 ];
29
30 this .button_bind.Enabled = true ;
31 }
32
33 private void button_bind_Click( object sender,System.EventArgse)
34 {
35 this .button_server.Enabled = false ;
36 this .button_passive.Enabled = false ;
37 this .button_start.Enabled = true ;
38 this .button_bind.Enabled = false ;
39 }
40
41 private void button_start_Click( object sender,System.EventArgse)
42 {
43 if ( this .radioButton_normal.Checked)
44 {
45 this .serverAgent.TestMode = TestMode.Normal;
46 }
47 else
48 {
49 this .serverAgent.TestMode = TestMode.FSOffline;
50 }
51
52 // 通过反射创建客户业务操作窗体
53 FormaddinForm = (Form)Activator.CreateInstance( this .passiveAddin.AddinFormType);
54 ((IPassiveAddinForm)addinForm).Initialize( this .serverAgent, " 000000 " );
55 addinForm.Show();
56 }
57
58 private void button_reset_Click( object sender,System.EventArgse)
59 {
60 this .textBox_passive.Clear();
61 this .textBox_server.Clear();
62
63 this .serverAgent.FunAddinManagement = null ;
64 this .passiveAddin = null ;
65
66 this .button_server.Enabled = true ;
67 this .button_passive.Enabled = true ;
68 this .button_start.Enabled = false ;
69 this .button_bind.Enabled = false ;
70 }
71

你可以在54行代码处添加断点,然后就可以跟入两个插件的源码中调试了。
需要注意的是,为了VS.NET能顺利的进入插件的源码,在加载插件时,最好直接加载插件工程Debug目录下的插件dll。

感谢关注!

转到: ESFramework 可复用的通信框架(序)

ESFramework介绍之(9)-- 插件对(Addin Pair)调试“框架”


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论