.NET 4.0 має новий GAC, чому?


300

%windir%\Microsoft.NET\assembly\є новим GAC . Чи означає це, що зараз ми маємо керувати двома GAC, одним для .NET 2.0-3.5 додатків та іншим для .NET 4.0 додатків?

Питання в тому, чому?


7
дякую, що
задали

2
Добре запитання ... Велике спасибі.
smwikipedia

1
+1 для вашого запитання. Я почав розробку під NET 4.0 і був збентежений "подвійною" проблемою GAC.
Ернан

3
Їм знадобилося кілька ітерацій, але Microsoft нарешті привів DLL пекло до .NET. Так!
нічогонеобхідне

Відповіді:


181

Так, оскільки існує два різних кеша глобальної асамблеї (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
Цей запис у блозі просто повторює відкриття ОП, але це не пояснює, чому потрібно розділити GAC. Це не очевидно, що оригінальний GAC міг би бути цілком здатним тримати 4.0 збірки окремо. У них є новий [AssemblyVersion]
Ганс Пасант

1
@Hans: Можливо, не точна причина, але вона говорить: "Щоб уникнути проблем між CLR 2.0 та CLR 4.0", також у цього питання було два питання. Другий питання: "чи означає це, що зараз ми маємо керувати двома 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% \. На жаль, це не було варіантом для цього випуску.

Сподіваюся, це допомагає майбутнім читачам.


3
Коментарі Міллера до пов'язаної статті надають інсайдерам погляд на цю тему.
Німеш Мадхаван

66

Це не має великого сенсу, оригінальний GAC вже цілком здатний зберігати різні версії збірок. І мало причин припускати, що програма коли-небудь випадково посилається на неправильну збірку, всі .NET 4 збірки отримали [AssemblyVersion] накопиченими до 4.0.0.0. Нова функціональна функція, яка знаходиться в процесі, не повинна змінювати це.

Я здогадуюсь: там уже було занадто багато .NET проектів, які порушили правило "ніколи нічого не посилаючись на GAC". Я бачив це на цьому сайті кілька разів.

Єдиний спосіб уникнути порушення цих проектів: переміщення GAC. Зворотний зв'язок є священним в Microsoft.


3
Це єдина відповідь, яка намагається пояснити, чому це так. +1
Ед С.

1
@Hans Passant: Що ви маєте на увазі під правилом "ніколи не посилайтеся ні на що в GAC безпосередньо"?
Макс Торо

2
@Max: на вашій машині є дві копії .NET збірок. Вони повинні бути еталонними збірками в c: \ windows \ microsoft.net і c: \ program файлах \ посиланнях. І ті, що використовуються під час виконання, GAC @ c: \ windows \ Assembly. Вони не однакові, 64-розрядні були б прикладом. Microsoft зробила все можливе, щоб ніхто не посилався на GAC з обробником розширення оболонки. І діалогове вікно Додати довідку. Не на 100% ефективність
Ганс Пасант

@Hans Passant: Пряма посилання - це щось на кшталт "c: \ WINDOWS \ Assembly \ GAC_MSIL \ System \ 2.0.0.0__b77a5c561934e089 \ System.dll", я не бачу, як додавання нової версії порушить цю посилання.
Макс Торо

2
@ Ханс Пасант: "І мало причин припускати, що програма колись випадково посилається на неправильну збірку". Я думаю, що ключовим тут є Assembly.LoadWithPartialNameте, що станеться, якщо у нас є дві версії збірки на GAC?
Макс Торо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.