Side-by-Side Assembly: механизм изоляции библиотек¶
Side-by-Side Assembly — механизм изоляции библиотек в средах выполнения .NET Framework и .NET, позволяющий одновременно загружать в один процесс несколько версий одной и той же сборки (assembly) без конфликтов. Данный подход обеспечивает независимое выполнение приложений и компонентов, которые ссылаются на разные версии общих библиотек, устраняя проблему «DLL hell» — ситуации, когда обновление одной библиотеки нарушает работу зависящих от неё программ.
¶История и предпосылки
Проблема конфликтов версий динамически подключаемых библиотек (DLL) возникла в операционных системах семейства Windows задолго до появления .NET. В классической модели Win32 приложение искало библиотеку в системном каталоге или в своей папке, и установка новой версии библиотеки могла привести к сбоям существующих приложений. С появлением .NET Framework (2002 год) корпорация Microsoft предложила принципиально иной механизм управления зависимостями, основанный на строгой идентификации сборок и возможности их параллельного размещения.
Первоначально side-by-side поддерживался только для сборок, помещённых в глобальный кэш сборок (Global Assembly Cache, GAC). Начиная с .NET Framework 2.0, механизм был расширен: стало возможным размещение нескольких версий сборки в каталоге приложения, что упростило развёртывание и обновление программ без административных привилегий.
¶Принцип работы
Каждая сборка в .NET характеризуется четырьмя параметрами: простым именем, версией, языком и регионом (culture) и криптографическим ключом издателя (public key token). Версия сборки состоит из четырёх частей: major, minor, build, revision. Именно эта полная идентификация позволяет среде выполнения различать сборки с одинаковым именем, но разными версиями.
Когда приложение запускается, среда CLR (Common Language Runtime) определяет, какие сборки необходимы, и загружает их в единое адресное пространство процесса. Если две разные сборки ссылаются на разные версии одной и той же библиотеки, CLR загружает обе версии в память. При этом типы с одинаковыми полными именами, но из разных версий сборки, рассматриваются как различные типы. Это означает, что объекты, созданные из разных версий, не могут быть напрямую присвоены друг другу без явного преобразования.
¶Роль политик версий
Для управления загрузкой версий используются конфигурационные файлы приложения (app.config), файлы издателя (publisher policy) и машинные политики. Политики позволяют перенаправлять запросы с одной версии сборки на другую, что даёт возможность централизованно обновлять библиотеки без перекомпиляции приложений. Однако принудительное перенаправление может привести к ошибкам, если новая версия библиотеки несовместима по API с ожидаемой.
¶Способы размещения
¶Глобальный кэш сборок (GAC)
GAC — системный каталог, в котором хранятся сборки, предназначенные для совместного использования несколькими приложениями. В GAC могут одновременно находиться несколько версий одной сборки. Установка сборки в GAC требует прав администратора и выполняется с помощью утилиты gacutil или установщика Windows Installer. Сборки в GAC обязательно должны иметь строгое имя (strong name), то есть быть подписанными ключом издателя.
¶Локальное размещение
Сборки могут храниться в каталоге приложения или в подкаталогах. В этом случае среда CLR ищет сборку по определённым правилам зондирования (probing). При локальном размещении также возможно наличие нескольких версий в отдельных подкаталогах, однако конфигурация обычно требует явного указания путей через элемент <codeBase> в конфигурационном файле.
¶Преимущества и ограничения
Основное преимущество side-by-side — стабильность и независимость приложений. Обновление библиотеки для одного приложения не влияет на другие, использующие старую версию. Это особенно важно для крупных корпоративных систем, где разные модули могут требовать разные версии зависимостей.
К ограничениям можно отнести увеличение потребления памяти, поскольку в процесс загружается несколько копий кода, а также потенциальные сложности при обмене данными между версиями. Кроме того, механизм не решает проблему конфликтов на уровне неуправляемого кода (native DLL), который по-прежнему подчиняется правилам Windows.
¶Сравнение с другими подходами
В современных версиях .NET (начиная с .NET Core 3.0 и далее) концепция side-by-side получила развитие через механизм AssemblyLoadContext, который позволяет создавать изолированные области загрузки сборок в рамках одного процесса. Это даёт более гибкий контроль над зависимостями, включая возможность выгрузки сборок из памяти. Однако классический side-by-side по-прежнему используется для обеспечения совместимости в .NET Framework приложениях и при работе с GAC.
¶Применение
Механизм активно используется в сценариях плагинной архитектуры, когда приложение загружает расширения, ссылающиеся на разные версии общих библиотек. Также он применяется при развёртывании веб-приложений на платформе ASP.NET, где каждая виртуальная директория может иметь собственный набор версий сборок.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →

