2011-02-01 34 views
0

高級別:我試圖構建一個控制檯應用程序(例如ConsoleApp.exe),它可以對引用ConsoleApp.exe中定義的某種類型的任何給定的DLL執行一些處理。如何在引用常見DLL的程序集之間傳遞引用類型?

我決定可能錯誤地認爲我需要一個ConsoleApp的伴侶DLL,它包含一些類型或類型(例如ConsoleClass),這些類型或類型可以被arbirary DLL引用。爲了解決這個問題,我不知道更好的方法,我在ConsoleApp解決方案中有兩個項目,一個是類庫(Proving ConsoleApp.dll),另一個是引用類庫項目的控制檯應用程序。

此時,我現在可以將我的ConsoleApp.dll複製到另一個獨立解決方案(例如OtherApp.dll)中另一個相對不相關的項目,並引用它,然後編寫一個消耗ConsoleClass實例的方法作爲參數。

現在,爲了任意處理這個OtherApp.dll,ConsoleApp.exe加載該程序集,在該程序集中實例化適當的類,然後調用該實例的正確方法。下面的相關線條有望提供我如何做這件事情的背景:

Assembly.LoadFrom(path_to_OtherApp_dll); 
... 
var x = (dynamic)Activator.CreateInstance(type_inside_OtherApp_dll); 
... 
var instance = new ConsoleClass(); 
x.some_method_call(instance); 

最終這會失敗。這似乎是因爲即使兩個項目(ConsoleApp.exe和OtherApp.dll)引用同一個DLL來定義ConsoleClass,運行時仍然認爲它們是不同的類型。

有什麼想法?

+0

`(動態)Activator.CreateInstance(T)`沒有意義。既然你知道你正在實例化什麼類型,爲什麼不直接強制類型化:`(T)Activator.CreateInstance(T)`(`T:= type_inside_OtherApp_dll`) – stakx 2011-02-01 21:15:15

+0

事實上,我甚至建議你刪除`dynamic` 。如果你在`x.some_method_call(INSTANCE)`上得到了一個編譯時錯誤,你就知道你傳遞了錯誤類型的對象,並且你以某種方式讓你在這兩個DLL項目中的程序集引用出錯。 – stakx 2011-02-01 21:20:13

+0

好吧,我投的是動態的,因爲我個人不知道如何投射到一個我不知道字面類名的類型。我有類型(type_inside_OtherApp_dll),但是這是通過反射收集的(我之前沒有提到過)。由於ConsoleApp在編譯時無法引用OtherApp.dll,因此我無法在我的代碼中將其轉換爲type_inside_OtherApp_dll。 – 2011-02-01 21:35:20

回答

0

是的,當ConsoleApp.dll被加載兩次時會發生這種情況。一旦通過主應用程序,再由插件使用其本地副本。一個類型的身份是由它加載的程序集決定的。

我不清楚這是怎麼發生的。您選擇的第一個武器是Fuslogvw.exe,將其設置爲記錄所有綁定。首先要做的就是修理插件項目,並將ConsoleApp.dll引用的Copy Local屬性設置爲False,這樣額外的副本就不會被意外使用。

將插件DLL複製到主應用程序生成文件夾是無可爭議的解決方案,您可以使用Assembly.Load()加載它們。或者使用.config文件的子目錄使用<probing>元素來允許CLR找到它們。

0

你認爲「運行時正在考慮它們是不同類型的」嗎?安裝程序是否以一些例外的錯誤結束? x變量中的方法是否會收到它無法識別的內容或什麼?

3
  1. 定義公共接口。把它放到它自己的interface.dll中。
  2. 參考interface.dll在你的插件。讓plugin.dll中的主類實現您的界面。
  3. 在exe文件中引用interface.dll。
  4. 使用Assembly.Load()或Assembly.LoadFrom()將插件加載到您的exe文件中。
  5. 使用CreateInstance()來創建插件類的實例。
  6. 只需將創建的插件轉換爲您的界面類型即可。

所以你不需要「動態」或其他複雜的東西。很簡單,按照我寫的步驟一步一步地工作。祝你好運。

相關問題