Смешивание .NET 3.5 с сборками 4/4.5 в одном и том же процессе
Я хочу перенести приложение .NET 3.5 WinForms на последнюю версию .NET(4.5).
В приложении используются "внешние" компоненты (которые можно рассматривать как плагины), которые также в настоящее время основаны на .NET 3.5.
Я хотел бы знать, какие библиотеки runtime/core используются в случае, если мы конвертируем ТОЛЬКО ПРИМЕНЕНИЕ для компиляции с использованием .NET 4.5?
Должен ли этот сценарий правильно работать? (загрузка .NET 3.5 сборок в процессе 4.5)?
* Модули плагина загружаются через отражение.
Как среда выполнения CLR обрабатывает такой сценарий? это безопасная практика?
Ответы
Ответ 1
Если вы перекомпилировали основной EXE-приложение для целевой .NET 4.x или используете файл app.exe.config с элементом <supportedRuntime>
, чтобы принудительно использовать CLR-версию 4, тогда вам не составит труда использовать как .NET 3.5, так и .NET 4.0. CLR v4 не имеет проблем с чтением 3.5 сборок, он совместим с обратной связью. Совсем наоборот, CLR v2 не может читать сборки версии 4, поэтому вам нужен файл .config, если ваш EXE не нацелен на v4.
Единственная морщина - это зависимости, которые ваша сборка 3.5 имеет на старых сборках фреймов. Он, например, попросит версию 2.0.0.0 mscorlib.dll. CLR автоматически переводит эти запросы и заменяет их версией 4.0.0.0. Что в целом прекрасно работает, стандартные сборки фреймов 4.0 очень совместимы со старыми версиями.
Однако Microsoft воспользовалась возможностью, когда 4.0 являлась новой бок о бок версией и фиксированными старыми ошибками, которые не могли быть легко исправлены без риска взлома кода, который случайно опирался на поведение с ошибкой. Они очень неясные ошибки, и вряд ли эти исправления ошибок будут бать вас. Однако вы должны повторно протестировать свой код, чтобы убедиться.
Ответ 2
Все сборки будут использовать типы из .NET Framework, на которые нацелено приложение.
Вот простой тест:
Проект Net2Library ", который является библиотекой классов .NET Framework 2.0 со следующим классом:
using System;
using System.Collections.Generic;
namespace Net2Library
{
public class Class1
{
public static List<string> GetStrings()
{
var strings = new List<string>();
Console.WriteLine("From Net2Library: {0}", strings.GetType().AssemblyQualifiedName);
return strings;
}
}
}
Проект Net4Application ", который представляет собой консольное приложение .NET Framework 4.0, которое ссылается на Net2Library.dll и имеет следующий класс:
using System;
using Net2Library;
namespace Net4Application
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("From Net4Application: {0}", Class1.GetStrings().GetType().AssemblyQualifiedName);
}
}
}
Выход консоли будет:
Из Net2Library: System.Collections.Generic.List`1 [[System.String, mscorlib, Версия = 4.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089]], mscorlib, Version = 4.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089 От Net4Application: System.Collections.Generic.List`1 [[System.String, mscorlib, Версия = 4.0.0.0, Культура = нейтраль, PublicKeyToken = b77a5c561934e089]], mscorlib, Версия = 4.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089
Вы также можете проверить следующие ресурсы:
. Обзор унификации сборки .NET Framework и Перенос привязки сборок.
Ответ 3
Если у вас есть сборка 3.5, ссылающаяся на исполняемый файл 4.5, обе сборки будут выполняться в среде 4.5 CLR. Однако сборка 3.5 будет нацелена на библиотеки v3.5, а не на v4.0 (хотя библиотеки 4.0 будут иметь все те же функции, что и 3.5 и более).
Итак, по крайней мере, по моему опыту, если вы хотите, чтобы сборки с таргетингом на 2.0-3.5 и другие сборки, ориентированные на 4.0-4.5, вам понадобятся версии 3.5 и 4.5 фреймворка, установленные на клиентском компьютере. 3.5 полностью обратно обратно совместим с 2.0, так что вы можете иметь 3.5, 3.0 и 2.0 все работает в одной среде. 4.0-4.5 совместим с большинством старых кодов, но есть некоторые нарушения (CAS - это один случай, который я недавно наткнулся), и вы должны явно указать 4.0 (или настроить ключ SupportedRuntime app.config).