具有强名称的C#插件架构:误解

时间:2009-09-02 17:38:42

标签: c# assemblies plugins key strongname

我有一个服务器可执行文件,它与Active Directory通信以检索用户信息。除了AD之外,这个exe还允许客户编写自己的插件来与自定义用户目录进行通信。

此可执行文件名称很强。

以下是真实陈述:

  

为了一个强烈的名字   组装加载另一个组件,   加载的程序集也必须签名   用同样的钥匙。

如果程序集没有强签名,则以下代码返回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接口的程序集,但也引用了一个程序集,它引用了另一个程序集,每个程序集都用不同的密钥签名。我尝试加载时会发生什么?他们都应该用同一把钥匙签名吗?

3 个答案:

答案 0 :(得分:9)

以下陈述是正确的:

  

为了强烈命名的程序集   加载另一个程序集   程序集也必须使用相同的密钥签署

来自MSDN

  

如果强名称汇编那么   引用一个简单的程序集   名称,没有这些   好处,你失去了你的好处   将来自使用强名称   汇编并恢复到DLL冲突。   因此,强名称的程序集可以   只参考其他有名的   组件。


修改:D'哦!虽然我的回答是正确的,正如P爸爸指出的那样,这是无关紧要的!

使用反射来加载名称较弱的程序集与引用程序集不同,并且不受同样的限制。

我使用以下程序集重新创建了您的代码(或至少近似值):

  • Interface.dll签名,包含IService

  • Loader.exe已签名,一个需要path的控制台应用,使用您的代码加载并返回它找到的第一个IServicepath指定的程序集,然后调用IService方法

  • Plugin.dll未签名,包含IService实施)

接下来,我添加了对Plugin.dll的{​​{1}}引用,并试图访问其Loaded.exe实现,该实现失败,如下所示:“程序集生成失败 - 引用程序集'插件“没有强大的名字。”

最后,我运行了控制台应用程序,传递了名称为IService的弱名称,它运行得很好。

似乎还有其他事情正在发生。 Scott Hanselman has blogged about the vagaries of dynamic assembly loading on several occasions,他指向Suzanne Cook's blog有关该主题的权威详细信息。

答案 1 :(得分:2)

如果您的程序集强类型签名,我认为您加载的任何程序集也必须强类型签名...但不一定使用相同的密钥签名。< / p>

答案 2 :(得分:2)

声明错误 - 引用的程序集必须已签名,但不一定使用相同的键。

  

当您引用强名称程序集时,您希望获得某些好处,例如版本控制和命名保护。如果强名称程序集然后引用具有简单名称的程序集(没有这些好处),则会失去使用强命名程序集并恢复到DLL冲突所带来的好处。因此,强名称程序集只能引用其他强名称程序集。

(取自MSDN Library