2

我的问题:

我有一个签名的程序集 A.dll,它的版本为 1.0.0.0 我有另一个引用 A.dll 的程序集(比如说 B.dll)。

一旦两个程序集都加载正常,没有任何问题。现在如果 A.dll 的版本更改为 1.0.0.1 并重新编译 B.dll 是否必须重新编译?

我问是因为我有这种确切的情况,在 A.dll 的版本更改后,我现在收到以下尝试加载 B.dll 的异常:

Unhandled Exception: System.IO.FileLoadException: 
    Could not load file or assembly A, Version=1.0.0.0, 
    Culture=neutral, PublicKeyToken…

这让我觉得这个问题的答案总是肯定的。但是,我有另一个示例,其中我有两个具有上述确切场景的程序集,并且加载程序集没有任何问题。

什么情况/条件导致此异常?如果有人可以对此提供一些见解,将不胜感激。谢谢。

4

2 回答 2

2

当一个程序集被强命名时,任何引用它的东西都会寻找那个特定的版本。

您是正确的,Visual Studio 中的“特定版本”不会以任何方式影响运行时。实际上,“特定版本”基本上意味着“当您运行构建时,如果 MSBUILD 找不到引用的版本,构建应该失败,还是只使用文件系统上可以找到的下一个版本?”

如果您重新编译 A 并将其部署为部分更新(而不是完全推出应用程序),那么如果应用程序中有任何引用旧版本的内容,您的应用程序可能会中断,除非您仍然拥有旧版本A 也可用(即您没有覆盖它)。

这是某些产品使用 GAC 的主要原因,因为它可以保存同一个 DLL 的多个版本而不会相互覆盖——如果您尝试将同一文件的不同版本部署到您的 bin 文件夹中(假设它们具有相同的文件名,他们通常会这样做),它们会相互覆盖,并且您最终只会在您的产品中使用 1 个 DLL!

您可以做的另一个技巧是将“重新版本化”的 DLL 放在二进制目录下的子文件夹中,然后编辑 app.config 以告诉运行时在哪里可以找到它们。 http://support.microsoft.com/kb/837908

因此,总而言之,强命名程序集不仅仅使用简单名称来确定程序集的身份——更改其版本可以被认为是完全更改其名称。

于 2011-10-26T03:17:38.827 回答
1

程序集 A 是否签名并不一定重要。您是否在项目 B 对 A 的程序集引用上使用“特定版本 = true”进行编译?如果是这样,那么 CLR 将使用严格的规则来确定给定版本的 A 是否可以接受。如果不是,那么 CLR 将使用不太严格的规则,并且如果 A 增加其版本,您将不需要重新编译。

根据您的环境,您可能不会担心 A 会在将来的版本中破坏兼容性。如果您不担心,那么您应该将程序集引用更改为“特定版本 = false”。(在工作中,我们有两种情况:例如,当我们依赖 3rd-party 控件时,我们通常强制“特定版本 = true”,但是当我们使用内部共享组件时,我们将针对使用它的应用程序,我们将确保“特定版本 = false”,因此我们不需要重新编译。)

您可以在 MSDN: Redirecting Assembly Versions上找到更多信息,包括当必须针对特定版本进行编译但希望稍后重定向绑定时如何通过配置文件规避此问题

希望有帮助!

于 2011-10-15T05:34:10.000 回答