2012-01-23 171 views
10

我有一個C#應用程序,我們稱它爲App.exe。它引用一個名爲A.dll的DLL,該DLL又引用另一個DLL,即B.dll。然而,它們被引用的方式有點不同。在A.dll的代碼中,它直接引用了B.dll(通過轉到Project> References> Add B.dll)。然而,我的App.exe有代碼加載A.dll在運行時使用Assembly.Load()等從另一個DLL引用一個DLL

所以回顧一下,App.exe ----(運行時加載)---> A.dll - - (直接引用)---> B.dll

所有這三件事(App.exe,A.dll和B.dll)都駐留在同一個目錄下,比如說ExeDir。現在我想要做的是將A.dll和B.dll放在ExeDir的子目錄中。我可以通過使用指定A.dll路徑並請求App.exe從該路徑加載A.dll的App.config文件來完成此操作。到現在爲止還挺好。

然而,問題是,當我這樣做時,.NET給我一個錯誤,說它無法找到與A.dll在同一目錄中的B.dll。如果我將它移回到原始目錄(與App.exe相同的目錄),那麼它工作正常。這意味着,我可以將A.dll放在一個子目錄中,但B.dll需要放在原始目錄中。

有沒有什麼辦法可以將兩個DLL保存在子目錄中?

回答

9

在你的app.config添加<probing>元素:

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="bin;bin2\subbin;bin3"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 
+0

感謝D斯坦利的回覆。但我在這裏有點不知所措。你能告訴我我到底該怎麼辦?只是用程序集路徑指定這個元素? – Sach

+1

是相對於您的EXE。例如,在MSDN示例中,活頁夾將在默認情況下在BIN文件夾中進行搜索,但也會搜索bin2文件夾,bin2 \ subbin文件夾和bin3文件夾。將'bin; bin2 \ subbin; bin3'替換爲A.dll和B.dll所在的文件夾(相對於EXE)。請注意,如果包含在A.dll中的路徑不再需要指定探測路徑。 –

+0

謝謝斯坦利,我讓它工作! 雖然這是我的錯,我沒有在這裏解釋我的完整問題。爲什麼我想要在不同的文件夾中的DLL的原因是我可能有幾個不同的A.dlls(內容不同),並且它們每個都可能引用B.dlls。所以我想實現更安全的代碼,例如,如果不同的A.dll想引用B.dll,其內部也可能有所不同。但看起來不能完成。不過,謝謝!你回答了我原來的問題。 – Sach

5

您可以通過爲當前AppDomain的AppDomain.AssemblyResolve事件提供事件處理程序來手動解析B.DLL程序集。

currentDomain.AssemblyResolve += ResolveLostAssemblies; 

然後提供ResolveEventHandler實現:

private Assembly ResolveLostAssemblies(object sender, ResolveEventArgs args) 
{ 
    // Find the assembly referenced by args.Name, load it dynamically, and return it. 
} 

我發現,這提供了該組件加載得到最大的控制和時間。它特別適用於你的應用程序是可插入的情況,每個插件都位於他們自己的「plugins」文件夾(不一定是應用程序目錄)的子目錄中。從技術上講,程序集甚至不必是使用這種方法的物理文件。雖然D斯坦利的方法通常被認爲更標準。

+0

謝謝巴布科克!我把它用於斯坦利的方法。 – Sach