如果A引用程序集B 1.1和C,而C引用B 1.2,那么如何避免程序集冲突?
我认为C的引用会被封装掉并且不会引起任何问题,但是看起来所有的dll都被复制到了bin,这就是问题发生的地方。
我理解这两种方法是使用GAC还是汇编绑定? GAC对我来说似乎不是最好的方法,因为我不喜欢假设dll会在那里,我更喜欢在我的解决方案中引用lib目录中的dll。
如果程序集绑定对我来说似乎不健壮,那么如果程序集的某个版本具有另一个版本的功能,那么这不会产生问题吗?
在我的情况下,因为我使用的是第三方dll使用旧版本的nHibernate,而不是我自己使用。
答案 0 :(得分:9)
我过去使用GAC获得了相同的结果,但您应该质疑您必须引用多个版本的原因,并尽可能避免使用它。如果您必须这样做,binding redirect可能对您有帮助。
另外,您还阅读了this吗?
答案 1 :(得分:7)
一种看似鲜为人知的方法是使用extern关键字。
要引用具有相同完全限定类型名称的两个程序集, 必须在命令提示符下指定别名,如下所示:
/r:GridV1=grid.dll
/r:GridV2=grid20.dll
这将创建外部别名GridV1和GridV2。要使用这些 程序中的别名,使用
extern
引用它们 关键词。例如:extern别名GridV1;
extern别名GridV2;
每个extern别名声明都引入了一个额外的根级别 与全局相似(但不在其中)的命名空间 命名空间。因此,可以不参考每个组件的类型 通过使用他们的完全限定名称,根植于 适当的名称空间别名。
在前面的例子中,GridV1 :: Grid将是网格控件 grid.dll和GridV2 :: Grid将是grid20.dll的网格控件。
答案 2 :(得分:3)
我被要求支持多个版本的程序集并找到了这个解决方案:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="MyAssembly" publicKeyToken="..." />
<codeBase version="1.1.0.0" href="MyAssembly_v1.1.0.0.dll"/>
<codeBase version="2.0.0.0" href="MyAssembly_v2.0.0.0.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
答案 3 :(得分:1)
您可以在配置文件中添加bindingRedirect element,以指定要在运行时使用的程序集版本。
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
答案 4 :(得分:1)
.NET运行时完全能够同时加载同一程序集的多个版本。但是,如果您要打开这些蠕虫,我强烈建议您严格命名您的程序集并使用Major.Minor。*命名方案以避免命名冲突。
我认为您不应该考虑使用(或不使用)GAC的“一刀切”的方法。如果您想自动使用随未来版本的DLL发布的新功能,GAC可能会非常好。当然,这种祝福的代价是新版本可能无法完全像你期望的那样工作:)。这些都是最实用的问题,以及对发布到GAC的内容的控制程度。
此致 -Alan。