【问题标题】:Why does loading System.Data 4.0.99.99 succeed?为什么加载 System.Data 4.0.99.99 会成功?
【发布时间】:2015-03-13 16:29:31
【问题描述】:

令我们惊讶的是,以下语句没有抛出异常!

Assembly.Load("System.Data, Version=4.0.99.99, Culture=neutral, PublicKeyToken=b77a5c561934e089");

GAC 仅包含版本4.0.0.0 - 没有4.0.99.99。请注意,尝试加载 4.1.0.0 失败。我们仅在 .NET 框架程序集上观察到了这种行为。

为什么会这样? .NET 框架程序集是否有任何默认程序集绑定重定向?是否还有其他魔法发生?

据我所知,只有在找到完全相同的版本时才应加载强名称程序集。

【问题讨论】:

  • 确实如此。如果为AppDomain.CurrentDomain.AssemblyResolve设置了事件处理器,上面的不会触发事件处理器;但是如果您更改程序集次要版本(例如更改为4.1.99.99)或公钥令牌,则会触发该事件。从那我猜,版本号的最后两个重要部分被忽略了。
  • 这有记录吗?我们仅对 .NET 框架程序集观察到这种行为。通常,如果定义了绑定重定向,您会期望这种行为 -> .NET 框架程序集是否有任何默认绑定重定向?
  • 我没有检查过,但也许System.Data 4.0 版有一个publisher policy file 可以进行重定向。
  • 检查您的 app.config 或 web.config 是否有任何绑定重定向。一些 Nuget 包添加了可能导致此问题的运行时绑定设置。
  • @Amy:谢谢,当然我们已经检查过了。我们甚至创建了一个最小的示例解决方案来绝对确定。

标签: c# .net .net-assembly


【解决方案1】:

正如 Hans Passant 在 cmets 中提到的,CLR 包含一个用于框架程序集的重定向机制,它将对旧框架库的引用重定向到新的框架库。您可以通过查看 Fusion Log(使用 fuslogvw.exe 并将其配置为记录所有绑定到磁盘)来查看该机制的工作,其中包含“框架配置中找到的版本重定向”信息:

LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\fabian.schmied\Desktop\Temp\ConsoleApplication3\ConsoleApplication3\bin\Debug\ConsoleApplication3.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Version redirect found in framework config: 2.0.0.0 redirected to 4.0.0.0.
LOG: Post-policy reference: System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
LOG: Found assembly by looking in the GAC.

在您的示例中,Fusion 日志包含等效行:

LOG: Version redirect found in framework config: 4.0.99.99 redirected to 4.0.0.0.

据此,我得出结论,相同的机制在这里发挥作用。似乎所有对 System.Data 的引用到 4.0.65534.65534 都被重定向到 4.0.0.0。

(对于从 4.1.0.0 开始的版本,重定向不再起作用。)

【讨论】:

  • 我也尝试在 CoreCLR 中定位这个机制。具体日志消息定义为ID_FUSLOG_FX_CFG_VER_REDIRECT,但我看不到这条消息实际发出的位置(github.com/dotnet/coreclr/…)。
  • 如果有人想深入研究,github.com/dotnet/coreclr/blob/… 似乎是一个不错的起点。 (github.com/dotnet/coreclr/blob/… 中还有一个遗留机制;但这似乎不会影响System.Data。)
  • 请记住,CoreCLR 源无法可靠地预测桌面 CLR 版本的外观。桌面版本要复杂得多,除了 SSCLI20 之外没有可用的资源。重定向是后来添加的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 2010-12-13
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
相关资源
最近更新 更多