黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

ESFramework介紹之(9)-- 插件對(duì)(Addin Pai

系統(tǒng) 2020 0
使用 ESFramework 開(kāi)發(fā) C/S (通常為 4 層、 3 層也沒(méi)問(wèn)題)應(yīng)用,當(dāng)需要增加一項(xiàng)新的業(yè)務(wù)時(shí),我們需要做的僅僅是開(kāi)發(fā)兩個(gè)插件,一個(gè)是服務(wù)端的業(yè)務(wù)功能插件(FunAddin),一個(gè)是客戶(hù)端插件( PassiveAddin ),這兩個(gè)插件合在一起稱(chēng)為 Addin Pair 。開(kāi)發(fā)這兩個(gè)插件,只需要關(guān)注于業(yè)務(wù),而其它與業(yè)務(wù)無(wú)關(guān)的比如網(wǎng)絡(luò)通信、加密、數(shù)據(jù)安全,都不用管。 ESFramework 很好的將這些關(guān)注點(diǎn)分離開(kāi)來(lái),使得寫(xiě)“業(yè)務(wù)”插件的程序員的工作變得非常單純,在 ESFramework 介紹之( 8 )-- 客戶(hù)端插件 IPassiveAddin 一文給出的一個(gè)開(kāi)發(fā)服務(wù)端功能插件和客戶(hù)端插件的示例中,大家應(yīng)該已經(jīng)體會(huì)到這點(diǎn)了。

正如 上文 結(jié)尾處提到,當(dāng)增加一項(xiàng)新的業(yè)務(wù),調(diào)試包含了這個(gè)新業(yè)務(wù)實(shí)現(xiàn)的插件對(duì)( AddinPair )時(shí)非常麻煩,因?yàn)樵? ESFramework 4 層架構(gòu)中,服務(wù)端功能插件加載于功能服務(wù)器( FS )上,客戶(hù)端插件加載在客戶(hù)端應(yīng)用程序上,中間的通信還經(jīng)過(guò)了應(yīng)用服務(wù)器(AS)。這樣就要將 AS FS Client 都啟動(dòng)起來(lái),才能對(duì)插件 Pair 進(jìn)行調(diào)試,并且在這樣調(diào)試的過(guò)程中,很多其它的因素會(huì)分散我們的注意力,比如多線(xiàn)程的影響、消息 Hook 的影響等等,這使得調(diào)試 Addin Pair 并不輕松,正是由于這個(gè)原因,促使我開(kāi)發(fā)一個(gè)插件調(diào)試框架來(lái)簡(jiǎn)化這個(gè)麻煩的過(guò)程。

我的想法是,在 VS.NET 調(diào)試模式中運(yùn)行這個(gè)“插件調(diào)試框架”(一個(gè) winForm 應(yīng)用程序),加載要調(diào)試的 Addin Pair ,然后,啟動(dòng) “業(yè)務(wù)操作窗體”顯示出來(lái),后續(xù)的交互將在兩個(gè)插件之間直接進(jìn)行通信,而 VS.NET 提供了我們跟蹤到加載的插件的源碼中的能力,這樣就可以調(diào)試 Addin Pair 了。 “插件調(diào)試框架”應(yīng)用程序的主界面如下:

ESFramework介紹之(9)-- 插件對(duì)(Addin Pair)調(diào)試“框架”

測(cè)試模式中的“異常(功能服務(wù)器掉線(xiàn))”用于模擬找不到對(duì)應(yīng)服務(wù)端功能插件的情況。

我們知道,客戶(hù)插件( PassiveAddin )通過(guò) IServerAgent 來(lái)發(fā)送請(qǐng)求獲取回復(fù),在客戶(hù)端應(yīng)用程序中, IServerAgent 是對(duì)底層 Tcp Udp 的封裝。在“插件調(diào)試框架”我們提供一個(gè) IServerAgent 的實(shí)現(xiàn)給要調(diào)試的 PassiveAddin 使用, ESFramework 給出的實(shí)現(xiàn)是 AddinBridge 類(lèi),它實(shí)現(xiàn)了 IServerAgent 接口,并且把 PassiveAddin 提交的請(qǐng)求直接提交給已加載的業(yè)務(wù)功能插件處理。 AddinBridge 實(shí)現(xiàn)如下:

AddinBridge
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> 1 /// <summary>
2 /// AddinBridge用于將服務(wù)端插件和對(duì)應(yīng)的客戶(hù)端插件橋接起來(lái),進(jìn)行調(diào)試。
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 /// 調(diào)試模式
72 /// </summary>
73 public enum TestMode
74 {
75 Normal,FSOffline
76 }



AddinBridge
借助了 IAddinManagement (插件管理器)來(lái)管理已加載的業(yè)務(wù)功能插件。

有了
AddinBridge 的支持,“插件調(diào)試框架”的實(shí)現(xiàn)就非常容易了,我將上圖主界面中的按鈕點(diǎn)擊事件源碼列在下面:

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( " 請(qǐng)選擇服務(wù)端插件 " , " .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 + " 請(qǐng)重新選擇插件! " );
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( " 請(qǐng)選擇客戶(hù)端插件 " , " .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 + " 請(qǐng)重新選擇插件! " );
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 // 通過(guò)反射創(chuàng)建客戶(hù)業(yè)務(wù)操作窗體
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行代碼處添加斷點(diǎn),然后就可以跟入兩個(gè)插件的源碼中調(diào)試了。
需要注意的是,為了VS.NET能順利的進(jìn)入插件的源碼,在加載插件時(shí),最好直接加載插件工程Debug目錄下的插件dll。

感謝關(guān)注!

轉(zhuǎn)到: ESFramework 可復(fù)用的通信框架(序)

ESFramework介紹之(9)-- 插件對(duì)(Addin Pair)調(diào)試“框架”


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論