2009-09-02 37 views
3

我有一個服務器可執行文件,與Active Directory進行通信以檢索用戶信息。除了AD之外,這個exe允許客戶編寫他們自己的插件來與自定義用戶目錄交談。具有強名稱的C#插件架構:誤解

此可執行文件是強命名的。

是以下一個真實的陳述:

爲了強命名 組件加載另一個裝配, 加載的程序集還必須使用相同的密鑰簽名 。

如果程序集沒有強有力的簽名,並且沒有錯誤指示程序集沒有正確簽名,那麼下面的代碼返回null。請注意,如果我簽署了程序集,我會得到一個IService的實例。這導致我相信加載的程序集必須進行強有力的簽名。

Assembly assembly = Assembly.LoadFrom(path); 

foreach (Type t in assembly.GetTypes()) 
{ 
    if (t.GetInterface(typeof(IService).FullName) != null) 
    { 
     return (Activator.CreateInstance(t) as IService); 
    } 
} 

那麼,這是否意味着,如果你有一個強簽名的程序集,並支持組裝的插件,他們也必須進行簽名 - 插件作者必須使用相同的密鑰簽名呢?這聽起來不對。假設我有一個實現了IService接口的程序集,但也引用了一個程序集,它引用了另一個程序集,每個程序集都用不同的鍵簽名。當我嘗試加載時會發生什麼?他們是否應該用同一把鑰匙簽名?

回答

9

下列說法正確的是:

爲了一個強名稱程序集 加載另一個組件,裝載的 組件也必須簽署 相同的密鑰

MSDN

如果強命名程序集,然後 引用的組件用一個簡單的 名稱,它不具備這些 好處,你失去的好處,你 會使用派生一個強名爲 程序集並恢復到DLL衝突。 因此,強名稱程序集 只能引用其他強名稱 程序集。


編輯:D'哦!雖然我的回答是正確的,正如P爸爸指出的那樣,這是無關緊要的!

使用反射來加載一個弱命名的程序集與引用之一的不是一回事,也不是以相同的方式進行限制。

我重新創建你的代碼(或至少一個密切近似),具有以下組件:

  • Interface.dll簽署,包含IService

  • Loader.exe簽署,一控制檯應用程序需要path,使用您的代碼加載並返回它在指定的程序集中找到的第一個IServicepath,然後調用一個IService法)

  • Plugin.dll沒有簽署,包含IService實現)

接下來,我添加了一個Plugin.dll參考Loaded.exe並試圖訪問其IService實現,它失敗如預期的那樣,出現以下消息:「程序集生成失敗 - 引用程序集」插件「沒有強名稱。」

最後,我運行了控制檯應用程序,傳遞了名字爲Plugin.dll的弱名稱,它工作得很好。

似乎還有其他事情正在進行。 Scott Hanselman has blogged about the vagaries of dynamic assembly loading on several occasions,並且他指向Suzanne Cook's blog以獲取關於該主題的權威細節。

+0

但這是否意味着在運行時用'Assembly.LoadFrom()'加載的程序集也需要簽名?我不這麼認爲。 – 2009-09-02 18:03:52

+0

@P爸爸:嗨,說說錯過了樹林。這是一個很好的問題 - 我也不這麼認爲。事實上,如果你在「Assembly.Load Strong Name」上搜索,你會發現一羣人在詢問如何執行強名稱要求。現在我對上面發佈的代碼的行爲感到困惑。 – 2009-09-02 19:10:16

2

如果您的程序集是強類型簽約,我想你加載任何組件還必須大力類型簽署......但不一定使用相同的密鑰簽名。

+0

強類型或強命名? – Alan 2009-09-02 17:42:22

+0

Doh ......我的手指超前了我的大腦。 – 2009-09-02 17:44:32

2

該聲明是錯誤的 - 引用的程序集必須簽名,但不一定使用相同的密鑰。

當您引用一個強名稱的程序集時,您希望獲得某些好處,例如版本控制和命名保護。如果強名稱程序集使用簡單名稱引用程序集,但沒有這些優點,則會失去使用強名稱程序集並導致恢復到DLL衝突的好處。因此,強名稱程序集只能引用其他強名稱程序集。

(來自MSDN Library兩者)​​