Блок, недоступный после Web.config, изменяется

Я использую пользовательскую платформу, которая использует отражение, чтобы сделать a GetTypeByName(string fullName) на полностью определенном имени типа, которое это получает от базы данных, чтобы создать экземпляр упомянутого типа и добавить его к странице, приводящей к стандартному модульному виду вещи.

GetTypeByName моя служебная функция, которая просто выполняет итерации через Thread.GetDomain().GetAssemblies(), затем работает assembly.GetType(fullName) найти соответствующий тип. Очевидно, этот результат кэшируется для дальнейшего использования и скорость.

Однако я испытываю некоторые проблемы, посредством чего, если web.config обновляется (и, в некоторых более страшных экземплярах, если пул приложений переработан) затем он потеряет все знание определенных блоков, приводящих к неспособности представить экземпляр типа модуля. Отладка шоу, что недостающий блок буквально не существует в списке блоков текущего потока.

Для обхождения этого, я добавил вторую проверку, которая немного грязна, но рекурсивно вызывает через DLLs/bin/каталога и проверяет, что каждый существует в списке блоков. Если это не делает, это загружает его с помощью блока. Загрузка и устранение проблемы контекста благодаря 'Решению проблемы Контекста Загрузки блока'.

Это работало бы, только кажется, что (и я знаю, что это не должно быть возможно), некоторые проекты все еще имеют доступ к недостающему блоку, например, мой фактический веб-проект, а не сама платформа - и это затем жалуется, что были добавлены дублирующиеся ссылки!

Кто-либо когда-либо слышал о чем-нибудь как это или имеет какие-либо идеи, почему блок просто выпал бы из существования на изменении конфигурации? За исключением решения, что самое изящное обходное решение должно заставить все блоки в мусорном ведре перезагружать? Это должно быть все в одном "хите" так, чтобы посетители сайта не видели различия кроме маленькой задержки, таким образом, файл app_offline.htm вне рассмотрения. Programatically, переименовывающий DLL в мусорном ведре и затем называющий его назад, работает, но требует, "изменяют" полномочия для учетной записи пользователя IIS, которая безумна.

Спасибо за любые указатели может собраться сообщество!

8
задан tags2k 3 April 2010 в 16:29
поделиться

5 ответов

Вообще, вам не следует полагаться на то, какие сборки в данный момент загружены в appdomain, поскольку это происходит динамически. Вместо этого просто вызовите System.Web.Compilation.BuildManager.GetType() вместо Type.GetType() или Assembly.GetType(). Это просто сделает то, что нужно, и не будет зависеть от циклов appdomain.

2
ответ дан 5 December 2019 в 22:17
поделиться

У меня аналогичная проблема, когда я обновляю 2–5 файлов, ether web.config, ether, другие файлы, а asp.net нужно воссоздать работающий files, то несколько раз не находил некоторые классы / функции, существующие в файлах dll, и моя система не работает - выкидывайте ошибки, подобные вашей.

Мое решение состоит в том, что я помещаю app_offline.htm в корневой каталог, делаю обновления, затем переименовываю / удаляю app_offline.htm, и моя система работает нормально.

Я уверен, что это имеет какое-то отношение к кэшированным скомпилированным файлам, но я не тщательно исследовал, что именно является причиной этого.

[самый элегантный обходной путь для перезагрузки всех сборок в корзине]

Самый элегантный обходной путь - это вызвать HttpRuntime.UnloadAppDomain и фактически заставить ваше приложение останавливаться и запускаться снова.

http://msdn.microsoft.com/en-us/library/system.web.httpruntime.unloadappdomain (VS.80) .aspx

Я не знаю, решит ли это вашу проблему, вам нужно сделать тесты.

возможно на Global.asax сделать что-нибудь подобное

void Application_Error(object sender, EventArgs e) 
{
   Exception ex = Server.GetLastError().GetBaseException();
   ...if ex is your error, and you get more than 2 ...
   {
     HttpRuntime.UnloadAppDomain();
   }
}
1
ответ дан 5 December 2019 в 22:17
поделиться

Я никогда раньше не слышал об этой проблеме.

Я не уверен, что это сработает, поскольку я только недавно прочитал об этом, исследуя обходные пути для зависимостей ODAC, но указание пути проверки для сборок может решить вашу проблему.

см .: http://msdn.microsoft.com/en-us/library/823z9h8w (VS.80) .aspx

пример:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>
1
ответ дан 5 December 2019 в 22:17
поделиться

Как вы, очевидно, знаете, существует множество ситуаций, когда текущий домен приложения выгружается и перезагружается . После каждой перезагрузки все сборки выгружаются и все приложение запускается «с нуля».

Сборки по умолчанию загружаются по запросу. Обычно это происходит, когда JIT натыкается на какую-нибудь ссылку.Как следствие, перезагрузка домена приложения приведет к удалению сборок в домене приложения, и они появятся снова только позже, когда JIT загрузит их.

В качестве решения я бы вернулся к использованию статического метода Type.GetType () и предоставил полное имя сборки (например, имя типа с включенным именем сборки). То же самое фреймворк использует при загрузке типов, указанных в файле конфигурации, и гарантирует, что требуемая сборка будет найдена и загружена по запросу без каких-либо уловок. См. Раздел примечаний к описанному выше методу (имя метода над именем является ссылкой).

Это потребует обновления вашей базы данных для хранения полных имен сборок вместо «только» полных имен типов. Однако он также гарантирует, что вы не столкнетесь с конфликтами имен, когда две сборки предоставляют разные типы с одним и тем же именем, так что в любом случае это хорошая идея, я думаю.

2
ответ дан 5 December 2019 в 22:17
поделиться

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

var temp = new BaseModuleBuilder();

Это не выглядит умным, но это очень прямолинейно, и asp.net должен сделать все за вас. В случае, если ваш список слишком динамический, это может быть что-то вроде

var temp = Activator.CreateInstance(Type.GetType("BaseModuleBuilder, Modules.dll"));

. Убедитесь, что вы всегда указываете DLL при работе с динамически загруженными классами.

0
ответ дан 5 December 2019 в 22:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: