使用外部程序集:定位的程序集清单定义与程序集引用不匹配

3

我知道这个问题似乎在stackoverflow和网络上都有答案,但我的问题是不同的。

我正在尝试了解如何在以下设置中不使用GAC(老板说不行):

该项目使用NHibernate和Antlr3.Stringtemplate,两者都是第三方程序集。NHibernate引用版本为3.1.3.42154的Antlr3.Runtime。Antlr3.Stringtemplate引用版本为3.3.1.7705的Antlr3.Runtime。

其中一个程序集不可用时,将引发错误。

我尝试了绑定重定向,但是由于两个版本之间的publicKeyToken不同,因此这种方法无效。结果它会寻找一个具有与3.1.3.42154版本相匹配的公钥令牌的3.3.17705版本。

将其中一个或两个安装到GAC中可以解决问题。但是,我的老板不允许我将任何内容安装到GAC中。

我还尝试将两个DLL放入BIN目录中,包括一个Lib项目和一个用于3.1.3.42154版本的文件夹。我告诉它始终复制,因此我得到/bin/Lib/3.1.3.42154/Antlr.Runtime.dll。然后我添加了探测元素来探测该目录。但是这没有起作用,我收到了完全相同的错误。

如何使用引用其他第三方程序集的第三方程序集,而两者引用不同的版本?

更新:

    System.Reflection.Assembly.LoadFile(@"Antlr3.Runtime.dll"); // 3.3.1        
    System.Reflection.Assembly.LoadFile(@"Antlr3.Runtime\Antlr3.Runtime.dll"); // 3.1.3

AppDomain.CurrentDomain.GetAssemblies() 显示应用程序域中加载的版本,但是,它仍然报错说找不到 3.1.3 版本。

以下是在调用出现错误的代码之前从 AppDomain.CurrentDomain.GetAssemblies() 中加载的内容。前两行是 GetAssemblies() 中的内容,第三行是错误信息提示缺少的内容。

{Antlr3.Runtime, Version=3.3.1.7705, Culture=neutral, PublicKeyToken=eb42632606e9261f}
{Antlr3.Runtime, Version=3.1.3.42154, Culture=neutral, PublicKeyToken=3a9cab8f8d22bfb7}
 Antlr3.Runtime, Version=3.1.3.42154, Culture=neutral, PublicKeyToken=3a9cab8f8d22bfb7

PublicKeyToken 不匹配导致程序无法运行。重新构建这些 DLL 并使用最新的引用是你唯一剩下的选择。 - Hans Passant
是的,我正准备下载NHibernate的源代码并重新编译它以引用stringtemplate使用的DLL。 - BradLaney
1个回答

1

问题已解决。

这是使用Antlr3.StringTemplate时的一个特定问题。Stringtemplate的作者实际上下载了antlr的源代码,并将其与他的应用程序一起构建,而不是分发原始的antlr dll。他的新antlr dll具有相同的名称,但具有不同的签名。他更改了版本和公钥令牌。因此,如果您尝试将原始dll与NHibernate等内容一起使用,则会导致非常严重的冲突。

因此,解决方案是使用ILMerge将他的自定义Antlr3 DLL合并到string.template DLL中,使string.template dll不依赖于任何东西。我将Antlr3.Runtime.dll、Antlr3.StringTemplate.dll和Antlr3.Runtime.Debug.dll合并为单个DLL Antlr3.StringTemplate.dll

这消除了所有DLL冲突,我能够包含nhibernate所需的Antlr3.Runtime.dll。Stringtemplate的作者也应该以这种方式分发他的软件包。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接