我的Visual Studio 2008项目引用了两个(外部)程序集(A + B),这两个程序集恰好引用了相同的第三个程序集(C)。但是,程序集A期望程序集C的公钥与程序集B期望的公钥不同。
这是一个明显例外的例子:
无法加载文件或程序集“Newtonsoft.Json,Version = 3.5.0.0,Culture = neutral,PublicKeyToken = 9ad232b50c3e6444”或其中一个依赖项。定位的程序集的清单定义与程序集引用不匹配。 (HRESULT异常:0x80131040)
当然,我不能在同一目录中放置两个版本的C(只有公钥不同),因为它们的文件名是相同的。其次,我发现使用配置文件中的程序集绑定只允许版本映射,而不是公钥映射。
我还尝试将其中一个程序集C放在一个单独的目录中,并将CLR配置为在加载程序集时在该目录中进行搜索。不幸的是,我无法让它工作。
我知道重新编译其中一个外部库(其中一个恰好是开源的)会解决这个问题,但如果不是绝对必要,我不想将这个负担添加到我的维护计划中。 / p>
所以我的问题是:如何引用程序集C的两个“版本”,它们只有公钥不同?
更新
我偶然发现了this answer一个相关的问题,使用ilmerge提供了一个有趣的解决方案。我还没有检查过它,但对于遇到这个问题的人来说这可能是有用的。
答案 0 :(得分:3)
我想知道AssemblyResolve
是否有效:
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name == "full name with old key")
{
return typeof(SomeTypeInReferencedAssembly).Assembly;
}
return null;
}
他是假设您引用了您的首选版本,并且可以使用SomeTypeInReferencedAssembly
类型来获取Assembly
;你也可以使用:
return Assembly.Load("full name with new key");
我没有尝试过,但在这里我基本上是说“部署一个版本的dll,当系统要求旧版本时 - 谎言”。
答案 1 :(得分:3)
你永远不应该有两个具有相同版本但不同公钥的程序集,这是一个灾难的处方。如果实际的装配版本不同,那么绝对最简单的解决方案是将它们放在global assembly cache(GAC)中。但是,如果你要处理在C中定义并在A和B中使用的类型的实例(例如,C声明MyType
,并且你获得了{{MyType
的实例,那么这将不会很好地发挥作用。来自B的1}}并将其传递给A.就运行时而言,这两种类型除了共享名称之外绝对没有任何关系。)
如果您正在寻找临时解决方案,那么我会选择Marc's;听起来它应该完美无缺。尽管如此,你走这条路的事实应该是一个巨大的红旗。