最近有個政府項目,客戶指定服務器程序必須跑在Linux上面,於是乎我們這幫Linux菜鳥立馬開裝Linux系統並部署Mono環境。因為對Linux實在不熟的緣故,故在RedHat Enterprise Linux 6中始終沒有將MonoDevelop跑起來,於是團隊中有同事提議“干脆轉Java平台算哒”,哎呦,這麼“反動”的想法必須得鎮壓在萌芽狀態。好吧,我承認有些許的個人主觀因素作祟,但終究還是需要些冠冕堂皇理由的:
因為公司現有所有產品都是基於.NET平台,絕大數開發人員也只有.NET開發經驗,這樣的平台遷移是個非常大成本的事件,而且涉及公司的整個軟件開發的方向性轉移,絕不可貿然行事。
我一直主張將所有產品統一開發平台,最終將各條產品線全部基於自己研發的插件框架,如果並行Java和.NET兩個開發平台,其中涉及的開發量和代碼移植、版本同步、雙向兼容……想想就是一個浩大而繁瑣的工程,這樣的焦油坑一定要避免陷入進去。
目前的問題其實只是團隊對Mono on Linux的經驗匮乏,這個問題還不至於嚴重到需要遷移開發平台,起碼我們還有Mono這樣一根救命稻草。所以,我們要做的只是盡快熟悉Linux和積累Mono on Linux上面的一些移植經驗,當然,我知道把C#代碼移植過去通過Mono的編譯並不難,問題在於有些API的細節差異和某些代碼契約需要通過一定時間的經驗來規避某些小陷阱,但是,這些都是可以解決的。
Mono現在最新穩定版本是2.10.2,對C# 4.0已經支持的很完整了。而且後面很快會有ASP.NET MVC3的完整實現,雖然沒有看到對ADO.NET EntityFramework的支持計劃,但是,我們曾經實現過以DataSet為數據載體的數據訪問框架,所以完全可以借鑒ADO.NET EF的設計思想去實現一個適度ORM數據引擎,當然這個事情得推後一點才有精力去做,但是想想就是一件多麼有趣的事情啊。
上面曉之以理,下面就該動之以情了,你看這次的Android版的警務通就是用Java來搞的,沒有使用那個MonoDroid吧,為啥?因為Mono for Android實在太不成熟了,用它寫的程序的無論是體積還是運行效率都沒法跟人家比,確實不在一個等級。總而言之,量體裁衣、具體對待。
部門會餐後,俺決定從這個項目組開始逐步進行雙機開發,每人配兩台電腦,一台裝Windows、一台裝Linux,在Windows中用VS開發,調試通過後簽入SVN中,再在Linux中簽出使用MonoDevelop進行一遍單元測試,不用虛擬機,一切原生態同步開發,提升每個開發人員對Linux的熟悉和積累對Mono on Linux的開發經驗,於公於私都是非常給力的!
RHEL6中MonoDevelop裝不上,咱沒功夫跟它耗,趕緊上OpenSUSE和CentOS,這兩個都是MonoDevelop官網的主薦平台,果然很給力相當的順。下面是今天(2011-7-5)將一些後台代碼移植到Mono on Linux中的實踐札記:
眾所周知Linux的文件系統路徑是區分大小寫的,所以在代碼中千萬不能簡單拼接文件路徑,推薦使用 System.IO.Path 類中的相關方法進行路徑操作,另外,對於文本中的分行要使用 Environment.NewLine屬性,或者 AppendLine 之類的方法來處理以規避操作系統的差異。
避免使用Win32 API的P/Invoke操作,這點好在Linux上只是跑服務器端代碼,所以基本不會涉及。
今天移植的兩個類庫時,只碰到下面兩個問題花了一點時間,就運行測試通過了,好爽。
一、在.NET 4.0的System.Type中新增了這個GetType(…)方法重載:
public static Type GetType(string typeName, Func<AssemblyName, Assembly>assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError)我的代碼是這樣使用的:
public static Type GetType(string typeFullName)