簡體   English   中英

C#中的接口和后期綁定

[英]Interfaces and Late Binding in C#

我之前在C#中為可正常工作的插件系統完成了此操作,這就是為什么我對為何這個新的獨立插件系統無法按我期望的方式工作感到困惑的原因。

我有我的插件程序集-我們稱之為“ plugin.dll”,而我有我的主程序集-我們稱之為App.exe。

我有一個名為IMyObject的接口,其實現MyObject都在plugin.dll中定義。 我已經將IMyObject的確切代碼文件(插件開發人員提供給我)復制到了我的主App.exe程序集中。

當我嘗試使用反射將加載的對象InvalidCastException為對象實現的接口時,會收到InvalidCastException 知道對象實現了它,因為

t.GetInterface(typeof(IMyObject).FullName) != null

是真的。 我還可以在Visual Studio的對象資源管理器中瀏覽MyObject ,可以看到它實現了IMyObject

這是出問題的地方:

 if (ifaceType != null)
 {
    ConstructorInfo constructor = ifaceType.GetConstructor(new Type[] { });

    if (constructor != null)
    {

       object obj = constructor.Invoke(null); // this works - obj is assigned an 
                                              // instance of MyObject

       IMyObject myObj = (IMyObject)obj;      // triggers InvalidCastException
    }               
 }

我現在所看到的與之前實現該方法之間的唯一區別是, 接口是在兩個單獨的程序集中定義的 (即使代碼文件是相同的,並且它們屬於相同的名稱空間)。

這是我麻煩的原因嗎? 如果是這樣,如何在編譯時不鏈接的情況下連接到我的插件,並使用插件本身定義的接口?

除了接口之外,我還應該添加該代碼,但我無權訪問該插件的源代碼。

即使這些接口具有相同的代碼,它們還是兩個不同程序集中的兩個單獨的接口(您可以打印它們的AssemblyQualifiedNames並查看不同之處)。

是的,運行時將接口視為不同類型。 它們具有相同的名稱。

沒有反射就無法使用宿主程序中的接口,因為您不能靜態鏈接它。 通常,將接口放置在插件主機程序集中,然后插件實現它們,而不是相反。

.NET中可擴展應用程序的典型框架包括以下程序集:

  • 合同組裝。 這包含插件的合同(僅接口,以及一些可選的數據合同,用於接口)和主機的合同。
  • 主機裝配。 這包含主機合同的實現,並取決於第一個。
  • 幾個插件程序集。 這些程序集包含插件合同實現,並且也依賴於第一個。

因此,通過使用合同匯編,您可以實現主機和插件彼此獨立(因此,插件后期綁定的),但是它們具有共同的合同,在編譯時雙方(插件和主機)都知道它們。

您的方式(多次定義插件聯系)是錯誤的方式。

正如其他人提到的那樣,這些是單獨的接口,處理此問題的正確方法是將定義放入第三個引用的程序集。

但是...有一種方法可以通過使用名為Impromptu Interface的庫來使其工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM