【问题标题】:Framework 4.5 assemblies are loaded when debugging a project targeted to the framework 4.0调试针对框架 4.0 的项目时会加载框架 4.5 程序集
【发布时间】:2012-09-25 21:29:04
【问题描述】:

我需要能够使用 Visual Studio 2012 以 .NET Framework 4.0 为目标,并验证我的代码在部署到我们的 4.0 环境 (Windows Server 2003) 时能够正常工作。

Visual Studio 2012 中的多目标功能似乎可以正常工作,但仅适用于mscorlib.dll。在引用任何其他框架 DLL 时,对于编译,您会得到正确的错误,例如引用了 4.0 中不存在的类型,但在执行和调试期间加载了 4.5 版本的 DLL。

考虑到 4.5 版本框架所做的就地升级中的重大更改,这使得无法验证我的代码是否可以在生产环境中正常工作。

我做了一些单元测试来测试多目标功能,通过练习在MSDN 上找到的 4.0 和 4.5 之间的一些差异。这些测试包含在他们自己的项目中,这些项目针对他们正在测试的框架版本。所有测试应该通过。

针对 MSCORLIB 的测试

这些测试成功通过,因为List<string> 位于mscorlib.dll

框架 4.0: -passes-

[TestMethod]
public void List_Foreach_should_not_throw_if_list_is_modified() {
    var list = new List<string> { "This", "here", "be", "a", "list", "of", "strings" };

    list.ForEach((s) => {
        if (s.Equals("be", StringComparison.OrdinalIgnoreCase)) {
            list.Add(".");
        }
    });
}

框架 4.5: -passes-

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void List_Foreach_should_throw_if_list_is_modified() {
    var list = new List<string> { "This", "here", "be", "a", "list", "of", "strings" };

    list.ForEach((s) => {
        if (s.Equals("be", StringComparison.OrdinalIgnoreCase)) {
            list.Add(".");
        }
    });
}

针对其他框架 DLL 的测试

但是这些测试不能正常工作(4.5 一个通过,4.0 一个不通过),因为这些类型在 System.ComponentModel.Composition.dll 中找到并且总是加载 4.5 版本:

Framework 4.0 - 失败,抛出 4.5-

预期的异常
[TestMethod]
public void Should_be_able_to_create_a_serializer_for_MEF_catalogs()
{
    var catalog = new AggregateCatalog();
    var serializer = new XmlSerializer(typeof(AggregateCatalog));
}

框架 4.5 -passes-

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Should_not_be_able_to_create_a_serializer_for_MEF_catalogs()
{
    var catalog = new AggregateCatalog();
    var serializer = new XmlSerializer(typeof(AggregateCatalog));
}

这是设计好的吗?考虑到 mscorlib 的 4.0 版本已加载但其他所有程序集的 4.5 版本,这似乎是不相交的。

有没有办法获得我想要的功能?

更新

这是我正在使用的solution/projects

【问题讨论】:

  • 您的所有参考资料都正确设置了吗?
  • 我们收到了 David Kean 关于单元测试行为的错误报告。我们将在未来的 VS 更新中调查并解决此反馈。 Mathew Aniyan Visual Studio 单元测试团队。

标签: visual-studio visual-studio-2012 multitargeting


【解决方案1】:

感谢您的精彩再现!

在查看您的项目时,有两件事会影响您的结果,从而导致您所看到的行为:

1) 当我们检测到在 4.5 下运行的 4.0 应用程序时,我们会“填充”更改 API 以返回旧的 4.0 行为,当我们认为它可以从合理(即非人为的)应用程序使用中观察到时。例如,依赖于在 List.ForEach 中修改列表的能力的 4.0 应用程序将继续看到 4.0 行为,无论是在 4.0 还是 4.5 下运行。 4.5 应用程序将看到新的行为。

为了确定我们认为合理的使用方式并指导我们填充的 API,我们有一个兼容性团队负责检查整个框架中的每一个“重大”更改,并将其与一组规则和指南进行比较我们在过去 10 年中建立起来的。

在您附加的项目中,您正在测试 5 件事:

  • 4.5以下的List.ForEach修改列表时抛出InvalidOperationException
  • Uri 低于 4.5 现在会在路径分段中保留拖尾点
  • 4.5 以下的 Uri 不再转义?在基于 file:// 的 URI 中
  • 4.5 下的 Enumerable.Empty 现在保证它返回相同的实例(这个在文档中有点误导 [我已经提交了一个错误],我相信 4.0 上的行为可以返回两个不同的实例第一次被多进程机器上的两个不同线程同时访问
  • MEF 的目录不再是 XML 可序列化的

在这些行为中,前三个被填充以在 4.0 应用程序运行时返回 4.5 上的先前行为。然而,最后两个没有填充。这是因为最后两个更改会破坏非常人为的应用程序用法,在这种情况下,我们只是将它们记录在上面作为仅供参考。例如,更改 MEF 目录,虽然理论上您可以使用 XML 序列化程序序列化这些类型(这是无意的,恕我直言,这是 XML 序列化程序的可怕行为),但您无法对结果做任何事情,因为它没有反序列化为任何有用的东西。

如果我们可以修改该页面以包含为 4.0 应用程序填充的重大更改列表,我正在追赶。

2) 我遇到的第二个问题是 4.0 测试项目与另一个基于 4.5 的测试项目在同一运行时被错误地检测为 4.5。您可以通过自己运行 4.0 测试来观察这一点,三个带垫片的测试将通过。将它们与 4.5 测试一起运行,它们会失败。我不确定这个问题在哪里发挥作用,但我已经在内部提交了一个错误,并与负责的团队启动了一个线程以深入了解它。如果您想在外部跟踪问题,请随时在http://connect.microsoft.com/VisualStudio 上提交错误,我们会将错误发送给正确的所有者。

大卫·基恩

CLR 团队

【讨论】:

  • 我有一个问题,我仍然没有在任何地方得到回答:为什么? 为什么所有这些复杂性和记录不充分的魔法,而不是简单地增加版本并“按预期”做所有事情在.NET 世界中?即使有良好的文档,这也永远不会变得清晰。就地升级是您在 .NET 世界中可以做的最糟糕的架构决策之一,那么为什么要将其应用于 .NET 本身呢?
  • 哇!感谢大卫非常详细的回复。了解了垫片的行为,现在一切都变得更有意义了。我非常感谢您抽出宝贵时间查看并回答。至于你的#2,我注意到了同样的行为,并且我对这个问题的看法不正确,认为这是相同的症状;即,也许所有测试都在加载了 4.5 程序集的共享 appdomain 下运行。我最终做了你提到的同样的事情,手动和独立地执行了两组测试。
【解决方案2】:

据我了解,这正是它应该如何工作的。您的计算机和 GAC 中没有 .NET 4.0。在运行时,您始终拥有 .NET 4.5,因为它是就地升级(安装 .NET 4.5 会覆盖 .NET 4.0)。引用的程序集和多目标仅适用于 IntelliSense、对象浏览器和 MSBuild(通常是设计时工具)。

【讨论】:

  • 如果这是真的,那么 Visual Studio 在调试针对框架 4.0 的项目时如何以及为什么加载 mscorlib.dll 的 4.0 版本,在调试针对框架的项目时加载 mscorlib.dll 的 4.5 版本4.5?
  • 今晚我会请开发人员详细回答这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
相关资源
最近更新 更多