MCP

вторник, 27 октября 2009 г.

GAC

Не выдержал и решил написать ответ на вопрос про GAC для конкурса Гайдара про платформу.

Переписывать MSDN и Рихтера не буду, для разнообразия скажу своё мнение про GAC, чтобы ответ отличался от остальных.   Собственно расскажу, не про то, чем хорош GAC, а чем он плох.

Для начала в двух словах про него — это глобальный кеш сборок, и любое приложение, которое использует опредёленную сборку сначала посмотрит на её наличие в GACе, а только потом будет искать в других местах. Т.е. можно считать GAC банальным хранилищем DLLек, как Windows\System32, но с одним важным отличием. Сборки хранятся не по имении библиотеки, а по имени, Strong Name ключу, версии, культуре и платформе (x86, x64). Т.е. можно хранить разные версии сборок и даже умудряться их использовать в одном приложении (хотя лучше постараться не делать так). Т.е. GAC полезная функциональность, но есть несколько НО.

Самое главное, теряется возможность xcopy deployment, необходимо использовать gacutil или делать приличный Installer. Но если подумать, то что нужно класть в GAC? Нужно туда размещать библиотеку, которую будут использовать несколько приложений на компьютере, иначе особого смысла в этом нет. Другими словами, это должен быть конкретный shared-компонент. А кому нужен shared-компонент? Только разработчикам. Для обычных пользователей это в большинстве случаев не нужно. А разработчики очень не любят сложные процессы установки библиотек. Им бы в проект скопировать что надо, и не думать потом о библиотеках. В противном случае получается, что у разработчика может всё работать, ибо сторонняя сборка в GACe, а у клиента уже всё будет падать, ибо разработчик забыл её приложить к приложению.

Например, мой epic fail был с библиотекой Microsoft.mshtml.dll, которая оказалось что ставится со студией, и напрямую в приложении не используется, а используется через третьи библиотеки. В результате, у меня приложение работало на всех компьютерах, а половина клиентов ругалась. Конечно, я уже умный, и подобных вещей стараюсь не допускать, но вот пример как легко можно сломать приложение использованием GACа.

Собственно, если мы планируем использовать сборку в GACе, то у нас сразу усложняется разработка. Необходимо писать скрипты для билда, которые будут выковыривать сборку из GAC, компилировать новую версию и вставлять обратно. Вроде не сложно, но программисты ленивые, и обязательно что-нибудь схалтурят, и при деплое получим проблемы.  Ещё нужно обязательно использовать Strong Name, что на этапе разработки иногда плохо, ибо придётся раздавать ключ всем разработчикам (проблема в секурности), также сразу включается версионирование, которое менять нужно вручную. Иначе получатся две абсолютно разных сборки с версией 1.0.0.0, одна из которых в GAC, а вторая нужна приложению, и это вызовет замечательные проблемы, которые будет очень весело отлаживать.


Собственно, что я хотел сказать:

  • Использовать GAC нужно, когда есть проблемы с версионированием. Это позволит их решить. Например, приложение А использует библиотеки B и С. B использует библиотеку D версии 1.0.0.0, а C использует D версии 1.2.0.0. Как это это необходимо решать. Тут нужен GAC, ибо два файла с одним именем к приложению подцеплять плохо.
  • Использовать GAC нужно, когда есть много приложений, использующих одну сборку. Как вариант — хостинг многих приложений с общим компонентом. И то, может быть проще не использовать GAC, ибо места на диске не так уж и много сэкономится, а если случайно выкинут сборку из GAC, то можно получить проблемы.
  • Хороший пример того, что нужно класть в GAC — системные библиотеки .NET Framework
  • Во всех остальных случаях — не стоит. (Моё личное мнение).

2 комментария: