我有一个与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接口的程序集,还引用了一个程序集,该程序集引用了另一个程序集,每个程序集都使用不同的密钥签名。尝试加载时会发生什么?是否都应使用相同的密钥签名?

最佳答案

以下说法是正确的:


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


MSDN


  如果是强名集会的话
  用简单的引用引用程序集
  名称,没有这些
  利益,你失去利益
  将源自使用强名称
  组装并还原为DLL冲突。
  因此,强名称程序集可以
  只参考其他强名
  组件。




编辑:哦!尽管我的回答是正确的,但正如P Daddy指出的那样,这无关紧要!

使用反射加载弱命名程序集与引用一个程序集不是同一回事,并且不受相同方式的限制。

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


Interface.dll(签名,包含IService
Loader.exe(已签名,一个使用path的控制台应用程序,使用您的代码加载并返回在该IService指定的程序集中找到的第一个path,然后调用IService方法)
Plugin.dll(未签名,包含IService实现)


接下来,我添加了对Plugin.dllLoaded.exe引用,并尝试访问其IService实现,该实现由于预期失败而显示以下消息:“程序集生成失败-引用的程序集'Plugin'没有强名称。”

最终,我运行了控制台应用程序,并为它传递了一个名称较弱的Plugin.dll的名称,并且运行正常。

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

10-08 18:41