基于.Net Remoting的项目总结报告
Based on .Net Remoting Project Summary Report<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
?
?
任務:將一個Windows forms的Client/Server程序改寫為基于.Net Remoting的程序,由IIS承載Remote Objects。
?
1,Windows form的Client/Server系統架構:
包含5個主要的子系統:WinUI(用戶界面部分),BusinessRules(業務邏輯部分),DataAccess(數據訪問部分),ApplicaitonFrameworks(負責系統參數配置和一些通用class),ExceptionManagement(負責所有系統的異常處理及log)
?
2,轉換為基于.Net Remoting系統的若干思路
本來準備將BusinessRules子系統部署為Remote Objects,標示為SAO(SingleCall/Singleton),但立即發現了一個問題。
因為Business Class幾乎都是Fileds成員變量+Public方法組成的,也符合對象技術的基本定義:將數據和操作行為(方法)包裝在一起。
如果將Remote Objects部署為SAO-SingleCall,任何對Remote Objects的Public Accessors賦值/調用都會產生新的對象實例,也就是說Remote Objects是無狀態的。
如果將Remote Objects部署為SAO-Singleton,顯然這樣也行不通,因為共享一個Remote Object實例,Fields成員變量會混亂。
?
雖然可以通過將方法參數直接傳入,完全不使用Fileds成員變量,這樣就可以解決上述問題,但是這樣存在很多問題:
(1)首先,程序修改工作量巨大,我最討厭這種沒有創造性的重復工作。
(2)在Class中不使用Fileds成員變量,我覺得這樣違背了對象技術的基本定義:將數據和操作行為(方法)包裝在一起。另外,也喪失了使用Fileds成員變量的好處,使程序的可讀性及可維護性下降。
(3)設想方法中包括N多的參數,并且多個方法都是類似的參數列表,顯然不能接受。或許有人提出可以采用參數類/Entity Class來傳參數,這樣會產生很多的參數類,并且也違背對象技術的基本定義。
?
***
這樣,可以考慮將Remote Objects部署為CAO(Client-Activated Object),CAO對象基本上和正常的.Net Object一樣。當在Client端發出創建實例對象的請求(通過Activator.CreateInstance() or new關鍵字),一個激活消息將發送到Server端,然后Client端的Proxy Object并獲取一個指向Remote Object的objRef對象。
CAO對象是有狀態對象(stateful object),Client端對Remote Object的屬性賦值后,可以在下一次正確讀取,并且CAO對象在每一次方法調用都保持狀態信息。
?
為了減少對WinUI/BusinessRules子系統的修改,顯然采用CAO對象的Direct/Transparent Creation方法,具體可以參考《MarshalByRefObjects遠程對象及其調用方法》,其中也有一些drawback需要注意。
?
我認為采用CAO來部署Remote Objects應該是可行的,不過我具體沒有測試過。如果有人測試過,希望能share這方面的體會。
?
***
具體項目中,因為DataAccess子系統基于SqlHelper.cs類(Microsoft Data Access Application Block v2.0),無法直接將SqlHelper.cs部署為Remote Objects,前面的posting《嘗試RemotingSqlHelper的若干問題》有詳細的討論。
?
雖然可以將SqlHelper.cs改寫為可以部署為Remote Objects對象,我也的確做了一些嘗試。正是由于《嘗試RemotingSqlHelper的若干問題》提及的一些局限,同時也避免對BusinessRules子系統的大量修改。
?
最終嘗試了如下的方法,并且在實際系統中驗證是可行的。
?
?
3,基于.Net Remoting 的系統架構:
具體思路是這樣的:
(1)將原來的DataAccess子系統部署為Remote Server,并改為RemoteDataAccess子系統,由于SqlHelper.cs不能直接部署為Remote Object,因此在外面包裝一個RemotingSqlHelper Class,將RemotingSqlHelper部署為Remote Object。
(2)增加新的DataAccess子系統,該子系統負責接受來自BusinessRules子系統的調用,因此需要偽裝為SqlHelper.cs的模樣,否則BusinessRules子系統需要修改的地方就多了。
(3)并且新的DataAccess子系統并不直接訪問SQL Server Database,而是訪問RemotingDataAccess子系統中的RemotingSqlHelper Class。
?
其中需要注意的問題:
(1)SqlConnection對象以connection string代替,我一直習慣使用connection string,因此這個也省事了。
(2)SqlParameter對象-我定義了一個可序列化的Class,在DataAccess端,將SqlParameter對象轉為可序列化的Class。然后在RemotingSqlHelper class中還原為SqlParameter對象,并調用真正的SqlHelper class。
?
這樣,整個轉換過程就大功告成了。其中BusinessRules子系統需要修改的地方很少,幾乎不用改。
?
不過,當有大量數據記錄從Server端傳遞到Client端時,比較明顯感覺到性能受到影響。Remote Server為IIS,Channel為HTTP(IIS不支持TCP Channel),Formatter為Binary。
?
在此,也感謝一些friends對上述Posts的回復/評論,對我有不少啟發。
?
當然,如果設計一個全新的基于.Net Remoting的系統,就不要費這么多周折了。
總結
以上是生活随笔為你收集整理的基于.Net Remoting的项目总结报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: maven中的snapshot来源与注意
- 下一篇: 用javascript缓存ajax数据