在调试面向框架4.0的项目时会加载Framework 4.5程序集

时间:2012-09-25 21:29:05

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

我需要能够使用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: - 通过 -

[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: - 通过 -

[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版本:< / p>

Framework 4.0 -fails,抛出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 - 通过 -

[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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

感谢伟大的复仇者!

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

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

为了确定我们认为合理使用的内容,并指导我们提供的API,我们有一个兼容性团队,负责查看整个框架中的每个“突破”变更,并将其与规则和指南集进行比较我们在过去十年中积累起来。

在您附加的项目中,您正在测试5项内容:

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

在这些行为中,当4.0应用程序运行时,前三个行为将在4.5上恢复以前的行为。然而,最后两个没有收缩。这是因为最后两个更改需要打破非常人为的应用程序使用,在这种情况下,我们只是将它们作为一个FYI记录在上面。例如,改变MEF目录,理论上你可以使用XML序列化程序序列化这些类型(这是无意的,而且恕我直言,XML序列化程序的一个可怕行为)你无法对结果做任何事情,因为它没有去除任何有用的东西。

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

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

David Kean

CLR团队