我的想法是,在VS.NET調試模式中運作這個“插件調試架構”(一個winForm應用程式),加載要調試的Addin Pair,然後,啟動“業務操作窗體”顯示出來,後續的互動将在兩個插件之間直接進行通信,而VS.NET提供了我們跟蹤到加載的插件的源碼中的能力,這樣就可以調試Addin Pair了。“插件調試架構”應用程式的主界面如下:
測試模式中的“異常(功能伺服器掉線)”用于模拟找不到對應服務端功能插件的情況。
我們知道,客戶插件(PassiveAddin)通過IServerAgent來發送請求擷取回複,在用戶端應用程式中,IServerAgent是對底層Tcp或Udp的封裝。在“插件調試架構”我們提供一個IServerAgent的實作給要調試的PassiveAddin使用,ESFramework給出的實作是AddinBridge類,它實作了IServerAgent接口,并且把PassiveAddin送出的請求直接送出給已加載的業務功能插件處理。AddinBridge實作如下:
AddinBridge
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 IAddinManagement funAddinManagement = null ;
14 public IAddinManagement FunAddinManagement
15 {
16 set
17 {
18 this.funAddinManagement = value ;
19 }
20 }
21
22
23 #endregion
24
25 #region TestMode
26 private TestMode testMode = TestMode.Normal ;
27 public TestMode TestMode
28 {
29 set
30 {
31 this.testMode = value ;
32 }
33 }
34 #endregion
35
36 #endregion
37
38 #region IServerAgent 成員
39 public NetMessage CommitRequest(Message requestMsg, DataPriority dataPriority, 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(IFunAddin funAddin 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 NetMessage CommitRequest(Message requestMsg, DataPriority dataPriority, 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的支援,“插件調試架構”的實作就非常容易了,我将上圖主界面中的按鈕點選事件源碼列在下面:
private AddinBridge serverAgent = new AddinBridge() ;
private IPassiveAddin passiveAddin = null ;
按鈕事件處理
1 private void button_server_Click(object sender, System.EventArgs e)
2 {
3 this.textBox_server.Text = FileHelper.GetFileToOpen("請選擇服務端插件" ,".dll") ;
4 IAddinManagement addinManager = 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.EventArgs e)
17 {
18 this.textBox_passive.Text = FileHelper.GetFileToOpen("請選擇用戶端插件" ,".dll") ;
19 IAddinManagement addinManager = 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.EventArgs e)
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.EventArgs e)
42 {
43 if(this.radioButton_normal.Checked)
44 {
45 this.serverAgent.TestMode = TestMode.Normal ;
47 else
48 {
49 this.serverAgent.TestMode = TestMode.FSOffline ;
50 }
51
52 //通過反射建立客戶業務操作窗體
53 Form addinForm = (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.EventArgs e)
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。
感謝關注!