2013-04-05 67 views
3

我們有一個我們分發的DLL,它具有對其他DLL的外部依賴關係。我們不是冒着丟失DLL或潛在混合和匹配的情況冒險,而是將DLL嵌入到我們自己的DLL/EXE中,並在運行時加載它以滿足運行時鏈接。將DLL嵌入到.NET DLL/EXE中時內存和CPU的影響?

問:

A)之間

  • 嵌入我們的.EXE/.DLL裏面的DLL,然後將其加載到內存在運行時 和
  • 保持作爲DLL一個單獨的文件在文件系統上,然後讓系統爲我們加載它

哪種方法消耗更多的內存和大約多少?

B)有沒有人比上述有更好的方法?尤其對於下方的項目#3中的詳細信息。在我們的過程


詳細的興趣:

  1. 註冊在我們知道運行在彙編代碼調用之前的部分AssemblyResolve事件(例如:初始時間)

    public void SomeInitCode() 
    { 
        ... 
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
        { 
         string[] assemblyDetail = args.Name.Split(','); 
         var assemblyName= assemblyDetail[0] + ".dll"; 
    
         var thisAssembly = Assembly.GetExecutingAssembly(); 
         var allResourceNames = thisAssembly.GetManifestResourceNames(); 
    
         string requiredResName = allResourceNames.SingleOrDefault(a => a.EndsWith(assemblyName)); 
    
         using (var input = thisAssembly.GetManifestResourceStream(requiredResName)) 
         { 
          return input != null 
           ? Assembly.Load(StreamToBytes(input)) 
           : null; 
         } 
        }; 
        ... 
    } 
    
    static byte[] StreamToBytes(Stream input) 
    { 
        var capacity = input.CanSeek ? (int)input.Length : 0; 
        using (var output = new MemoryStream(capacity)) 
        { 
         int readLength; 
         var buffer = new byte[4096]; 
    
         do 
         { 
          readLength = input.Read(buffer, 0, buffer.Length); 
          output.Write(buffer, 0, readLength); 
         } 
         while (readLength != 0); 
    
         return output.ToArray(); 
        } 
    } 
    
  2. 嵌入程序集。這是通過「添加現有項目」到.NET項目=>選擇.dll =>確定完成的。回去選擇.dll,然後在屬性中將「構建操作」更改爲「嵌入式資源」。

  3. 我們仍然需要添加相同的.DLL作爲參考,並且仍然需要在使用它的類的頂部有using ExternalNamespace;語句。如果沒有,構建過程將失敗,因爲它在編譯時無法看到外部DLL代碼。因此,作爲後期製作操作,我們必須從最終的bin文件夾中刪除.DLL文件(不是嵌入式克隆)。

+0

匿名'close'選民:至少說出來。 – DeepSpace101 2013-04-05 00:12:03

+0

您不能讓安裝程序處理依賴關係嗎? – 2013-04-05 00:16:54

+0

不錯,但是,這是一個獨立的不安裝發行版 – DeepSpace101 2013-04-05 00:43:51

回答

1

答:只要將內部組件本身不具有一定的規模龐大(一些大規模的嵌入式資源,例如)它應該工作可接受 - 這是一個有點wriggly的答案,但我沒有比「衡量」更好的了。我偶爾做過非常類似的事情(和類似的原因)。 B:在參考屬性(f4)上設置「複製本地」爲False。即使文件位於同一個項目中,您也需要using ExternalNamespace; - 這只是將名稱空間帶入其中。

2

正如Marc所建議的那樣。

我只是用ILMerge把所有東西都扔在一起。

但是它可能不可行,但應該適用於'純'託管程序集(包括使用unsafe的程序集)。