1. 程式人生 > >C#程式集載入方法

C#程式集載入方法

     要從程式集的元資料中獲取程式集的資訊,首先需要載入程式集。.Net中載入程式集方法有幾種,本人結合自己的實踐和認識簡單介紹一下。描述不一定很準確,請提出來一起進步。

一、隱式載入
        沒有被顯式載入但被引用的程式集,CLR會按照全域性程式集快取(GAC)、工作目錄(應用程式所在目錄)以及私有路徑目錄的順序來尋找並載入。

二、AppDomain.Load 方法
    將一個程式集載入到一個特定的程式域中,主要用來供非託管程式碼呼叫

三、Assembly.Load方法
    通過接受一個程式集標識來載入程式集。如果是強命名程式集,則標識包括程式集名稱、版本、語言文化、以及公有金鑰標記,Load方法將導致CLR按照隱式載入的策略尋找並載入程式集。弱命名程式集

則只是一個不帶副檔名的程式集的名稱,CLR不會到GAC中查詢,如果沒有指定私有目錄,則在工作目錄查詢,如Assembly.Load("Math")。其中私有目錄的定義可以在配置檔案中指定。如應用程式MyApp.exe的配置檔案可以定義為MyApp.exe.config。內容:
    

  1.  <?xml version="1.0" encoding="utf-8" ?>
  2.     <configuration>
  3.        <runtime>
  4.           <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
    >
  5.              <probing privatePath="App;App1;" />
  6.           </assemblyBinding>
  7.        </runtime>
  8.     </configuration>

     其中App和App1是兩個在工作目錄下的目錄,用probing定義,存放需要在這個目錄下被載入的程式集。如果使用工作目錄以外的目錄下的程式集,則可以使用codeBase元素來定義,可以在MSDN上查詢其屬性內容。

四、Assembly.LoadFrom方法
    引數是包括程式集清單的檔案的名稱或路徑,包括副檔名。如需要載入D:/App/math.dll,可以使用語句:
    Assembly a = Assembly.LoadFrom(@"D:/App/math.dll");
    a即是載入的程式集。
    但這種方法有缺點,在MSDN上有詳細的描述,我自己遇到的一個問題是載入一個在非工作目錄下的程式集後,在另一個程式集中使用這個程式集中的物件進行反序列化時失敗。使用Assembly.Load方法或者將該程式集放在工作目錄下後問題得以解決。

五、Assembly.LoadFile方法
    用來載入指定路徑上的程式集檔案的內容。使用 LoadFile 方法來載入和檢查具有相同標識但位於不同路徑中的程式集。與 LoadFrom 不同,LoadFile 不會將檔案載入到 LoadFrom 上下文中,也不會使用載入路徑解析依賴項。LoadFile 在這個受限制的方案中很有用,因為 LoadFrom 不能用於載入標識相同但路徑不同的程式集;它只加載第一個這樣的程式集。

六、Assembly.LoadWithPartialName方法
    使用部分名稱從應用程式目錄或從全域性程式集快取載入程式集。引數為程式集標識,其中包含程式集的名稱(不帶副檔名)。程式集的版本、語言文化及公用金鑰標記為可選。該方法執行時CLR首先檢查應用程式的XML配置檔案來搜尋qualifyAssembly元素,若存在則該元素應能告訴CLR如何將一個部分的程式集標識對映為完全限定的標識,CRL將根據通常規則來查詢程式集。若該元素不存在,CRL將使用指定名稱在應用程式的工作目錄和私有路徑目錄中搜索。若仍未找到,則到GAC中查詢。

七、傳統VC動態庫的呼叫
    通過 P/Invoke 呼叫Win32 DLL

    using System.Runtime.InteropServices;//這是用到DllImport時候要引入的程式集

    [DllImport("DBAccess.dll",CharSet=CharSet.Auto)]
    static extern ulong FindApp( bool bIsTrue );
    //宣告外部的標準動態庫,跟Win32API是一樣的.