Сборки Framework 4.5 загружаются при отладке проекта, ориентированного на Framework 4.0.

Мне нужно иметь возможность ориентироваться на.NET Framework 4.0 с помощью Visual Studio 2012 и проверять, будет ли мой код работать правильно при развертывании в нашей среде 4.0 (Windows Server 2003).

Многоцелевой таргетинг в Visual Studio 2012, кажется, работает правильно, но только для mscorlib.dll, При обращении к любой другой платформе DLL для компиляции вы получаете правильные ошибки, например, для ссылки на тип, который не существует в 4.0, но версия 4.5 DLL загружается во время выполнения и отладки.

Это делает невозможным проверку правильности работы моего кода в производственной среде с учетом серьезных изменений в обновлении на месте, которые внесла версия 4.5 платформы.

Я провел несколько модульных тестов, чтобы протестировать функциональность мульти-таргетинга, используя некоторые различия между 4.0 и 4.5, обнаруженные в MSDN. Тесты содержатся в их собственных проектах, ориентированных на версию платформы, которую они тестируют. Все тесты должны пройти.

Тесты против MSCORLIB

Эти тесты успешно проходят как List<string> находится в mscorlib.dll:

Framework 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(".");
        }
    });
}

Framework 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(".");
        }
    });
}

Тесты против других библиотек инфраструктуры

Эти тесты, однако, не работают правильно (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

[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 для всех остальных сборок.

Есть ли способ получить желаемую функциональность?

Обновить

Вот решение / проекты, которые я использую.

2 ответа

Решение

Спасибо за отличное воспроизведение!

Когда вы смотрите на ваш проект, на ваши результаты влияют две вещи:

1) Когда мы обнаруживаем приложение 4.0, работающее под 4.5, мы "подкладываем" измененные API-интерфейсы, чтобы вернуть старое поведение 4.0, когда считаем его наблюдаемым при разумном (то есть не надуманном) использовании приложения. Например, приложение 4.0, которое полагалось на возможность изменять список в List.ForEach, продолжит видеть поведение 4.0 независимо от того, работает ли оно под 4.0 или 4.5. 4.5 приложения увидят новое поведение.

Чтобы определить, что мы считаем разумным использованием, и руководствоваться API-интерфейсами, которыми мы руководствуемся, у нас есть команда по совместимости, которая отвечает за рассмотрение каждого "прорывающего" изменения во всей среде и сравнение его с набором правил и рекомендаций, которые мы " за последние 10 лет.

В проекте, который вы прикрепили, есть 5 вещей, которые вы тестируете:

  • List.ForEach под 4.5 создает исключение InvalidOperationException при изменении списка
  • Uri до 4.5 теперь сохраняет точки в хвостовых сегментах
  • Ури под 4.5 больше не убегает? в файле://- на основе URI
  • Enumerable.Empty под 4.5 теперь гарантирует, что он возвращает тот же экземпляр (этот немного вводит в заблуждение в документах [я подал ошибку], я считаю, что поведение было на 4.0, что он мог вернуть два разных экземпляра в первый раз, когда он доступ к двум различным потокам одновременно выполнялся на машине с несколькими процессами)
  • Каталоги MEF больше не сериализуемы в XML

Из этих поведений первые три подменяются, чтобы вернуть предыдущее поведение на 4.5, когда запущено приложение 4.0. Принимая во внимание, что последние два не переливаются. Это связано с тем, что в результате последних двух изменений потребовалось бы очень надуманное использование приложений, и в этом случае мы просто документировали их выше как FYI. Например, возьмите изменение каталога MEF, хотя теоретически вы могли бы сериализовать эти типы, используя сериализатор XML (который был непреднамеренным и ИМХО ужасным поведением сериализатора XML), вы ничего не могли сделать с результатом, так как он этого не сделал. Десерализовать на что-нибудь полезное.

Я надеюсь, если мы сможем изменить эту страницу, чтобы включить список критических изменений, которые подкладываются для приложения 4.0.

2) Вторая проблема, с которой я столкнулся, заключалась в том, что тестовый проект 4.0 неправильно определялся как 4.5, когда они были в том же запуске, что и другой тестовый проект на основе 4.5. Вы можете наблюдать это, запустив тесты 4.0 самостоятельно, и три пройденных теста пройдут. Запустите их вместе с тестами 4.5, и они не пройдут. Я не уверен, где эта проблема вступает в игру, но я подал ошибку внутренне и начал поток с ответственной командой, чтобы добраться до сути. Если вы хотите отслеживать проблему извне, не стесняйтесь сообщать об ошибке по http://connect.microsoft.com/VisualStudio и мы направим ее к нужным владельцам.

Дэвид Кин

Команда CLR

Насколько я понимаю, именно так и должно работать. На вашем компьютере и в вашем GAC нет.NET 4.0. Во время выполнения у вас всегда есть.NET 4.5, потому что это обновление на месте (установка.NET 4.5 перезаписывает.NET 4.0). Сборки со ссылками и многоцелевой таргетинг работают только для IntelliSense, Object Browser и MSBuild (инструменты времени разработки в целом).

Другие вопросы по тегам