国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

減少生成的dll數量

2019-11-17 02:13:59
字體:
來源:轉載
供稿:網友

減少生成的dll數量

  在開篇之前我想鄙視我自己一下,這個東西根本不需要去寫,本來已經有東西去實現了,正如我組長說我的,看的開源項目太少了。其實這個東西完全可以用ILMerge來解決。

  然后再說說前言,開發東西久了,總會積累到一定量的Helper或Util,于是都放到一個項目里面一起編一個dll,用的時候就方便,可是問題來了,像SQLite這種Helper需要帶上它的dll,再多封裝幾個類,附帶的dll就更多了,有時候想單單用一個很簡單的Helper,結果還帶了一大堆不相干的dll,會不爽,而且有種感覺是引用時就單純一個Common.dll就夠了,什么System.Data.SQLite.dll,System.Data.MySQL.dll我都不想帶,在一次使用內嵌資源時給流我靈感,把這堆dll在編譯的時候都放到項目資源中,需要的時候就去加載,這樣就行了。

  單純這個就用到了內嵌資源使用方面的知識,另外一個就是AppDomain對dll加載方面的知識。

  在使用內嵌資源時,要把資源包含在項目里面,內嵌的資源在屬性頁面上"生成操作"選擇"潛入資源",

  在編碼時要把資源用上,得用流來讀取,通過Assembly的GetManifestResourceStream(string name);方法就可以把資源的流獲取到,流到了就愛干嘛干嘛,代碼如下

 1             Stream s = null; 2             byte[] dllDatas = null; 3             try 4             { 5                 s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Consoleapplication2.ClassLibrary1.dll"); 6                 dllDatas = new byte[s.Length]; 7                 s.Read(dllDatas, 0, dllDatas.Length); 8             } 9             catch (Exception ex)10             {11                 return null;12             }13             finally14             {15                 if (s != null)16                 {17                     s.Close();18                     s.Dispose();19                 }20             } 

dll的流拿到流,使用它的地方就在AppDomain的AssemblyResolve事件,當應用程序域加載外部的程序集時,它會默認往兩個地方找,第一是往.NET Framework的目錄中找,再到應用程序所在目錄中找,所以在默認情況下我們開發的類庫都會跟引用程序放到一個目錄,而經常用到的System.dll才不需要放到引用程序目錄中。那假如需要的dll沒辦法從這兩個地方找到的話,程序會拋出FileNotFoundException異常,這個仍然有辦法解決的,其實在拋出FileNotFoundException異常之前,AppDomain會先觸發AssemblyResolve事件,這個事件會返回這個無法找到的程序集,返回的程序集為空,才會拋FileNotFoundException異常,只要我們注冊了AssemblyResolve事件,在綁定的方法中把dll從資源中取出來,加載上程序集之后,無法在文件目錄中找到的程序集就可以加載到程序域中,程序集中的類可以照常使用

代碼如下

 1 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 2  3  4         static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 5         { 6  7             Stream s = null; 8             byte[] dllDatas = null; 9             try10             {11                 s = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication2.ClassLibrary1.dll");12                 dllDatas = new byte[s.Length];13                 s.Read(dllDatas, 0, dllDatas.Length);14             }15             catch (Exception ex)16             {17                 return null;18             }19             finally20             {21                 if (s != null)22                 {23                     s.Close();24                     s.Dispose();25                 }26             }27             Assembly assembly= AppDomain.CurrentDomain.Load(dllDatas);28             return assembly;29         }

  但是存在一個問題,這個AssemblyResolve事件在封裝的Common項目中注冊比較合適,可是AssemblyResolve事件應該是主動調用的,而Common里面的類全都是被調用的,個人覺得這個AssemlbyResolve事件可以放到Helper類的靜態構造函數里面,此外也暫時想不出更好辦法,或者這種方式本身不是一個好的方式。

  后續在開發中也發現一個問題,假如這個Common.dll在別的程序集也是通過AssemblyResolve事件被加載到程序域中的時候,這些在Common.dll里面通過AssemlbyResolve事件加載進來的程序集有問題。此問題還暫時無法解釋,估計要學習一下CLR方面的知識。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 娱乐| 监利县| 韶关市| 南宁市| 济源市| 鱼台县| 凤凰县| 四川省| 新邵县| 若尔盖县| 新郑市| 楚雄市| 合水县| 肇庆市| 广南县| 申扎县| 永清县| 股票| 崇明县| 西和县| 磐安县| 婺源县| 寿光市| 九龙坡区| 密云县| 镇平县| 西充县| 布尔津县| 慈利县| 青田县| 鄂伦春自治旗| 阿拉善右旗| 永福县| 赞皇县| 桃园市| 耒阳市| 金塔县| 昌邑市| 铁岭县| 永丰县| 汝阳县|