Прости меня, кодер, потому что я согрешил. Я поместил некоторый код в dll в GAC, и теперь я озадачен тем, как GAC действительно работает с IIS.
В нашей среде интрасети у меня есть несколько связанных веб-приложений (около 10). Каждое приложение запускается из отдельного URL-адреса и потенциально запускается в своем собственном пуле приложений. На данный момент все приложения находятся на одном сервере, но это не обязательно. Эта настройка позволяет нам контролировать, разрабатывать и переносить каждое приложение отдельно. Однако есть несколько частей каждого приложения, которые мы хотели бы использовать во всех наших приложениях (главные страницы, страницы входа, меню и т. Д.). Запрос от руководства состоял в том, что изменения в этих файлах могут быть универсальными и вступать в силу без необходимость перекомпиляции и перенастройки каждого веб-приложения. Есть много способов выполнить эту задачу, и, несмотря на предупреждения об избежании GAC, это действительно выглядело как случай, когда использование поставщика виртуального пути и DLL, хранящихся в GAC, имело смысл.
Я собрал провайдера Virtual path, а затем внедрил файлы и ресурсы, которые мне нужны, чтобы быть общими в DLL. (Я мог бы заставить VPP извлекать файлы из базы данных, но я надеялся, что встраивание файлов в саму dll будет более производительным.
Осложнение # 1
Я не хотел, чтобы разработчикам каждого приложения приходилось связываться с их собственным GAC для тестирования и запуска их приложения, поэтому в каждое решение я просто включил проект провайдера виртуальных путей и сделал его результат dll, скопируйте локально, (а также строго названный), это означает, что dll провайдера вместе со своими внедренными файлами копируются в каталог bin приложения. Пока разработчик не имеет версию этого dll в своем GAC (что они не должны), используется локальная копия bin. Это позволяет разработчику легко изменять и тестировать как файлы приложения, так и файлы, которые являются общими для каждого приложения.
Это также означает, что, если это не было намеренно предотвращено, общие dll будут существовать в каталоге bin каждого приложения в производстве. Однако, поскольку IIS всегда будет использовать версию GAC, если она существует, даже если локальная версия устарела, версия GAC всегда используется.
На данный момент я принял это как разумное решение, так как не мог найти простой способ, чтобы скопировать VPP.dll локально для разработки и, тем не менее, не скопировать в каталог bin, когда приложение было скопировано на сервер.
Осложнение № 2
На самом деле кодирование приложения таким образом, чтобы оно всегда использовало последнюю версию библиотеки DLL вместо конкретной версии, с которой оно было скомпилировано, кажется довольно сложным делом. (Мне еще не удалось найти хороший пример того, как это сделать, но я думаю, что мне понадобится цепочка политик издателя.) Казалось, гораздо проще попробовать более очевидный ответ - оставить номер версии dll неизменным при переносе нового версия VPP dll для GAC. Казалось, это работало нормально, пока не получилось.
Используя Windows / оснастку сборки на сервере, я заменил более старую версию v. 1.0.0.0 моей библиотеки DLL в GAC обновленной копией v. 1.0.0.0. Хотя я обновил dll в GAC, мои приложения продолжали использовать старую версию кода. Перезапуск IIS и даже полная перезагрузка сервера, похоже, не помогли. Что меня по-настоящему удивило, так это то, что в конечном итоге IIS загадочно и неожиданно исправит себя и начнет использовать правильную копию dll из GAC.
Я видел много связанных с GAC вопросов такого типа, которые, казалось, заканчивались тем, что «вдруг мой веб-сайт снова начал работать правильно». Мне потребовалось некоторое время, чтобы понять, что это было следствием того, что IIS кэшировал мою строго названную dll, и что я неправильно использовал способ, которым строго названные dll должны были работать.
Далее я попробовал гвыбрав версию dll из GAC полностью. Поскольку в каталоге bin все еще была копия моей dll, я ожидал, что процесс либо завершится с ошибкой, либо вернется / продвигается к версии, которая была в каталоге bin. Однако, поскольку версия в корзине была также 1.0.0.0, IIS продолжал использовать кэшированную копию библиотеки DLL, которой теперь больше не было на компьютере. (Это на какое-то время меня действительно расстроило, потому что я потерял уверенность в том, что GAC версия вообще работала)
Наконец, единственный способ, которым я должен был обязательно получить dll для обновления, - это удалить копию dll из GAC, удалить копию dll из каталога bin, запустить сайт, чтобы он вышел из строя, а затем Поместите новую версию DLL в GAC. Запуск и остановка IIS во время этого не имели никакого эффекта. Это постоянно заставляло мои приложения использовать новый код, но…
Так много для того, чтобы просто вставить новую версию dll в GAC и обеспечить беспрепятственное распространение ее новых эффектов.
После прочтения некоторых смежных вопросов я пытаюсь:
- Остановка IIS
- Обновление программного обеспечения библиотеки DLL в GAC (но при этом номер версии остается
новая dll на 1.0.0.0)
- удаление всего в
«C: \ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ Temporary
Папка ASP.NET Files (я так думаю
вызывает перекомпиляцию, но это
кувалда починки)
- перезагрузите IIS.
Кажется, это работает, но все же кажется, что что-то не так с необходимостью идти на все эти неприятности. Есть ли более простой способ заставить IIS использовать текущий экземпляр DLL GAC? Есть ли лучший способ добиться эффекта, которого я добиваюсь. (некоторые распространенные файлы .aspx и .xml открывают общий доступ к различным приложениям, которые можно обновлять отдельно от самих приложений.)
Редактировать: на основе комментария от шахкальпеша я нашел эту страницу в Microsoft
http://msdn.microsoft.com/en-us/library/7wd6ex19(VS.80).aspx
Это включало в себя этот маленький кусочек знания:
Перенаправление версий сборки
Чтобы перенаправить одну версию в другую, используйте элемент <bindingRedirect>
. Атрибут oldVersion может указывать либо одну версию, либо диапазон версий . Например, <bindingRedirect oldVersion="1.1.0.0-1.2.0.0" newVersion="2.0.0.0"/>
указывает, что среда выполнения должна использовать версию 2.0.0.0 вместо версий сборки между 1.1.0.0 и 1.2.0.0.
Что означает, что вместе с моей dll я мог выдвинуть один файл политики издателя, в котором все перенаправлено до последней версии. Такого рода смягчение того, что я считал кошмарной цепочкой политик, где мне приходилось поддерживать связь от каждой возможной версии до самой последней ...
Я попробую это и посмотрю, запускает ли обновление, подобное этому, также IIS, чтобы использовать правильную версию нового файла (после сброса пула приложений)