Почему некоторые сборки .Net недоступны через метод GetAssemblies () AppDomain?

У меня есть небольшой фрагмент кода, который перебирает типы, загруженные в настоящее время в AppDomain, который выполняется в приложении ASP.NET. Вот как получаю сборки:

var assemblies = AppDomain.CurrentDomain.GetAssemblies();

Когда приложение запускается впервые, проблем нет, и присутствуют все ожидаемые мной типы. Но когда я обновляю Web.config или убиваю процесс w3p.exe (или процесс перезапускается по какой-либо причине), доступны только некоторые из ожидаемых мной типов. Когда я перехожу к отладчику, я замечаю, что некоторые сборки из частного пути поиска (каталог bin моего приложения) не были загружены. Я исходил из предположения, что все сборки загружаются при запуске приложения и перезапускаются независимо от того, требовались они немедленно или нет. Но в случае перезапуска этого, похоже, не происходит , если эти файлы сборки не были обновлены.

Мне нужно собрать информацию о типе при запуске для использования позже. Но поскольку во время перезапуска типы недоступны, позже, когда потребуется использовать информацию о типе, будет пахнуть хаосом. Итак, имея это в виду, как я могу решить этот недостаток или обойти его?


person Jonathon Watney    schedule 09.09.2009    source источник


Ответы (3)


Можно ли при запуске явно загрузить какие сборки вам небезразличны?

Вам нужно будет заранее знать, какие сборки вам понадобятся.

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

person Nader Shirazie    schedule 10.09.2009
comment
Подумывал явно загрузить сборки. Пока мне нужны только частные сборки, чтобы я мог просто загрузить все из частного пути поиска. Я не уверен, что лучше всего сделать это. Сборка. Нагрузка? Assembly.LoadFile? Assembly.LoadFrom? - person Jonathon Watney; 10.09.2009
comment
Assembly.Load в целом является предпочтительным подходом, поскольку он наиболее близок к нормальному механизму загрузки. См. blogs.msdn.com/suzcook/archive/2003/05 /29/57143.aspx, чтобы узнать о преимуществах и недостатках, и blogs.msdn.com/suzcook/archive/2003/09/19/57248.aspx для получения дополнительной информации. - person Nader Shirazie; 10.09.2009
comment
Спасибо за ссылки, я их уже просмотрел. Думаю, мне придется использовать LoadFrom или LoadFile, поскольку у меня есть только пути к файлам, с которыми можно работать. Я знаю, когда я использовал LoadFile, прежде чем у меня возникли проблемы с обновлением сборок во время развертывания из-за блокировки файлов сборки, предположительно из-за LoadFile. Я думаю, что LoadFrom подходит мне, но я не уверен, что полностью понимаю его значение. - person Jonathon Watney; 10.09.2009
comment
Если у вас есть только пути, с которыми можно работать, можете ли вы проверить эти сборки, чтобы определить пути? Важно правильно определить контекст привязки. Кроме того, что касается проблем с блокировкой файлов, вам следует закрыть пул приложений во время развертывания - это завершит процесс IIS и предотвратит блокировки. Если вы не хотите этого делать, другой вариант - сделать то же, что и ASP.NET: создать теневые копии (techbubble.net/Blog/tabid/57/EntryId/148/) - person Nader Shirazie; 11.09.2009
comment
Надер, еще раз спасибо. Я просто не знаю, как определить, какой контекст привязки мне подходит. Пока что LoadFrom работает, и я, насколько могу, убедился, что у меня ожидаемое поведение. Но опять же, именно так казалось, прежде чем я заметил, что у меня есть эта проблема. :) - person Jonathon Watney; 11.09.2009
comment
Если вы позволите .NET работать нормально, он будет использовать контекст загрузки. Если по какой-то причине выполняется попытка загрузить сборку в контекст загрузки, у вас может быть проблема. Вы, вероятно, сможете справиться с этим, обработав AppDomain.AssemblyResolveEvent, хотя ... см. stackoverflow.com/questions/416468/ для чего-то подобного. Мы применяем аналогичный подход (AssemblyResolve + LoadFrom), и пока он работает хорошо ... - person Nader Shirazie; 11.09.2009
comment
Думаю, я нашел подходящее решение, используя предпочтительный подход Assembly.Load. Поскольку у меня есть пути к сборкам, я могу найти их имена с помощью AssemblyName.GetAssemblyName, а затем вызвать Assembly.Load, используя имя сборки. Пока все работает, и это должно избежать каких-либо проблем в разных контекстах. - person Jonathon Watney; 11.09.2009

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

person codymanix    schedule 09.09.2009
comment
Это правда, я не загружал ни одного из типов при запуске приложения. Проблема в том, что мне нужна информация о типе при запуске приложения, чтобы я мог использовать эту информацию позже. Если информация недоступна при запуске, приложение может вылететь позже. - person Jonathon Watney; 10.09.2009
comment
вы можете использовать статический метод Assembly.Load (), чтобы обеспечить загрузку всех необходимых сборок, когда они вам понадобятся. - person codymanix; 11.09.2009
comment
Я не могу использовать Aseembly.Load (), потому что у меня нет доступных имен сборок. Возможно, вы захотите проверить ответ Надера, чтобы узнать, где я нахожусь. - person Jonathon Watney; 11.09.2009

Ты можешь использовать

AssemblyName[] assemblies = Assembly.GetCallingAssembly().GetReferencedAssemblies();

Таким образом, вы получите все сборки, на которые есть ссылки из сборки, из которой вы вызываете этот метод.

person codymanix    schedule 10.09.2009
comment
Моя вызывающая сборка не обязательно ссылается на типы, которые мне нужны. - person Jonathon Watney; 11.09.2009
comment
Но, возможно, на них ссылается другая сборка, на которую ссылается ваша сборка. Вы можете пройтись по всему дереву сборок с косвенными ссылками, чтобы получить все сборки / типы, которые вам нужны. - person codymanix; 11.09.2009
comment
Ах я вижу. Я могу сделать это. Я должен посмотреть, как это влияет на время запуска. Спасибо. - person Jonathon Watney; 11.09.2009
comment
Оказывается, я не могу этого сделать, поскольку вызывающая сборка и даже исполняющая сборка даже косвенно не ссылаются на интересующие меня типы. - person Jonathon Watney; 11.09.2009