.NET 4.0 имеет новый GAC, почему?


300

%windir%\Microsoft.NET\assembly\это новый GAC . Значит ли это, что теперь нам нужно управлять двумя GAC, один для приложений .NET 2.0-3.5, а другой для приложений .NET 4.0?

Вопрос в том, почему?


7
спасибо, что задали вопрос .. я также очень смущен, когда я не нашел gac в его первоначальном месте :)
Jasl

2
Хороший вопрос ... Большое спасибо.
smwikipedia

1
+1 за твой вопрос. Я начал разработку под NET 4.0 и был смущен «двойной» проблемой GAC.
Эрнан

3
Им потребовалось несколько итераций, но Microsoft наконец-то вывела DLL Hell в .NET. Ура!
ничего ненужного

Ответы:


181

Да, поскольку существует 2 отдельных глобальных кэша сборок (GAC), вам придется управлять каждым из них в отдельности.

В .NET Framework 4.0 GAC претерпел несколько изменений. GAC был разделен на два, по одному для каждого CLR.

Версия CLR, используемая как для .NET Framework 2.0, так и для .NET Framework 3.5, представляет собой CLR 2.0. В предыдущих двух выпусках фреймворка не было необходимости разделять GAC. Проблема взлома старых приложений в Net Framework 4.0.

Чтобы избежать проблем между CLR 2.0 и CLR 4.0, теперь GAC разделен на частные GAC для каждой среды выполнения. Основное изменение заключается в том, что приложения CLR v2.0 теперь не могут видеть сборки CLR v4.0 в GAC.

Источник

Зачем?

Похоже, что из-за изменения CLR в .NET 4.0, но не в 2.0 до 3.5. То же самое произошло с 1.1 до 2.0 CLR. Кажется, что GAC имеет возможность хранить разные версии сборок, если они принадлежат одному CLR. Они не хотят ломать старые приложения.

См. Следующую информацию в MSDN об изменениях GAC в 4.0 .

Например, если и .NET 1.1, и .NET 2.0 совместно используют один и тот же GAC, то приложение .NET 1.1, загружая сборку из этого общего GAC, может получить сборки .NET 2.0, тем самым нарушая приложение .NET 1.1.

Версия CLR, используемая как для .NET Framework 2.0, так и для .NET Framework 3.5, представляет собой CLR 2.0. В результате этого не было необходимости в двух предыдущих выпусках платформы для разделения GAC. Проблема взлома старых (в данном случае .NET 2.0) приложений вновь появляется в Net Framework 4.0, после чего выпущен CLR 4.0. Следовательно, чтобы избежать проблем помех между CLR 2.0 и CLR 4.0, GAC теперь разделен на частные GAC для каждой среды выполнения.

Поскольку CLR обновляется в будущих версиях, вы можете ожидать того же. Если меняется только язык, вы можете использовать тот же GAC.


18
Этот пост в блоге просто повторяет открытие OP, но не объясняет, почему GAC нужно было разделить. Это не очевидно, оригинальный GAC был бы вполне способен поддерживать отдельные сборки 4.0. У них новая [AssemblyVersion]
Ганс Пассант,

1
@ Ханс: Может быть, не точная причина, но она говорит: «Чтобы избежать проблем между CLR 2.0 и CLR 4.0», у вопроса также было 2 вопроса. Второй вопрос: «Значит ли это, что теперь мы должны управлять двумя GAC, один для приложений .NET 2.0-3.5, а другой для приложений .NET 4.0?»
Брайан Р. Бонди

2
Вы должны процитировать это по одной из ваших ссылок: «Например, если и .NET 1.1, и .NET 2.0 совместно используют один и тот же GAC, то приложение .NET 1.1, загружающее сборку из этого общего GAC, может получить сборки .NET 2.0. , тем самым нарушая приложение .NET 1.1. "
Макс Торо

67

Я также хотел бы знать , почему 2 GAC и нашел следующее объяснение Марка Миллер в разделе комментариев в .NET 4.0 имеет 2 Global кэш сборок (GAC) :

Марк Миллер сказал ... 28 июня 2010 12:13

Спасибо за пост. «Проблемы вмешательства» были намеренно расплывчатыми. На момент написания статьи проблемы все еще находились в стадии изучения, но было ясно, что было несколько сломанных сценариев.

Например, некоторые приложения используют Assemby.LoadWithPartialName для загрузки самой высокой версии сборки. Если наивысшая версия была скомпилирована с версией v4, то приложение v2 (3.0 или 3.5) не смогло бы загрузить его, и приложение зависло бы, даже если бы существовала версия, которая работала бы. Первоначально мы разделили GAC по его первоначальному расположению, но это вызвало некоторые проблемы со сценариями обновления Windows. Оба этих кода включали в себя уже поставленный код, поэтому мы перенесли наш GAC с разделением версий в другое место.

Это не должно иметь никакого влияния на большинство приложений и не добавляет никаких затрат на обслуживание. Оба местоположения должны быть доступны или изменены только с использованием собственных API GAC, которые имеют дело с разделением, как и ожидалось. Места, где это происходит, - через API, которые предоставляют пути GAC, такие как GetCachePath, или проверку пути mscorlib, загруженного в управляемый код.

Стоит отметить, что мы изменили расположение GAC, когда мы выпустили v2, а также когда мы представили архитектуру как часть идентификатора сборки. Те добавили GAC_MSIL, GAC_32 и GAC_64, хотя все они все еще находятся в% windir% \ assembly. К сожалению, это не вариант для этого выпуска.

Надеюсь, это поможет будущим читателям.


3
Комментарии Миллера к связанной статье действительно дают взгляд инсайдеров на эту тему.
Нимеш Мадхаван

66

Это не имеет большого смысла, оригинальный GAC уже вполне способен хранить разные версии сборок. И нет никаких оснований предполагать, что программа когда-либо будет случайно ссылаться на неправильную сборку, все сборки .NET 4 получили [AssemblyVersion] повышенную до 4.0.0.0. Новая функция в процессе работы не должна изменить это.

Мое предположение: уже было слишком много проектов .NET, которые нарушили правило «никогда не ссылаться на что-либо непосредственно в GAC». Я видел это на этом сайте несколько раз.

Единственный способ избежать разрушения этих проектов: перенести GAC. Back-compat является священным в Microsoft.


3
Это единственный ответ, который пытается объяснить, почему это так. +1
Эд С.

1
@Hans Passant: Что вы подразумеваете под правилом «никогда не ссылаться на что-либо непосредственно в GAC»?
Макс Торо

2
@Max: на вашем компьютере есть две копии сборок .NET. Это должны быть ссылочные сборки в c: \ windows \ microsoft.net и c: \ program files \ ссылочные сборки. И те, которые используются во время выполнения, GAC @ c: \ windows \ assembly. Они не одинаковы, 64-битный будет примером. Microsoft сделала все возможное, чтобы никто не ссылался на GAC с помощью обработчика расширения оболочки. И диалог Добавить ссылку. Не эффективен на 100%
Ханс Пассант

@Hans Passant: Прямая ссылка - это что-то вроде 'c: \ WINDOWS \ assembly \ GAC_MSIL \ System \ 2.0.0.0__b77a5c561934e089 \ System.dll', я не вижу, как добавление новой версии нарушило бы эту ссылку.
Макс Торо

2
@Hans Passant: «И нет никаких оснований предполагать, что программа когда-либо будет случайно ссылаться на неправильную сборку». Я думаю, что ключ здесь в том Assembly.LoadWithPartialName, что произойдет, если у нас будет 2 версии сборки в GAC?
Макс Торо
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.