程序集加载版本不匹配:为什么要加载?

Ian*_*Ian 5 .net dll assemblies

我有两个程序集:HelloWorld.exe 和 Hello.dll。exe 是主程序集,主程序集正在使用 dll。

我编译了 HelloWorld.exe (1.0.0) 和 Hello.dll (1.0.0)。我将程序集放在不同的文件夹中。

然后我将 Hello.dll 的版本更改为 2.0.0,并继续用 2.0.0 版本覆盖 Hello.dll 1.0.0。然后我启动 HelloWorld.exe 并且它运行良好。

我预计它会立即崩溃并烧毁,因为我编译 EXE 时引用的 Hello.dll 是 1.0.0。现在,1.0.0 DLL 已被 2.0.0 取代,但它仍然有效!

根据MSDN

默认情况下,程序集将仅使用与构建和测试时完全相同的程序集(名称和版本号)中的类型。也就是说,如果您的程序集使用另一个程序集 1.0.0.2 版中的类型,则它(默认情况下)不会使用另一个程序集 1.0.0.4 版中的相同类型。使用名称和版本来标识引用的程序集有助于避免升级到一个应用程序破坏其他应用程序的“DLL 地狱”问题。

问题:

  1. 为什么有效?
  2. 如何使它不起作用?
  3. 额外问题:在构建过程中会发生什么?外部依赖的版本不是硬编码到主要依赖中吗?

请注意,Hello.dll 不是强命名的。

这是 HelloWorld.exe 的清单:

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly extern Hello
{
  .ver 2:0:0:0
}
.assembly HelloWorld
{
...//snipped
}
Run Code Online (Sandbox Code Playgroud)

这是从 Fuslogvw.exe (Assembly Binding Log Viewer) 获取的程序集绑定日志:

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly extern Hello
{
  .ver 2:0:0:0
}
.assembly HelloWorld
{
...//snipped
}
Run Code Online (Sandbox Code Playgroud)

jga*_*fin 1

为什么它有效?

因为你已经指定了;)

如何让它不起作用?

  1. 右键单击“解决方案资源管理器”中的 DLL
  2. 选择属性
  3. 选择使用特定版本

额外问题:构建过程中会发生什么?外部依赖项的版本不是硬编码到主要依赖项吗?

除非您指定,否则不会。默认情况下它是关闭的。设计良好的程序集应该向后兼容,并且版本并不重要。