ASP.NET забывает DLL в каталоге bin

У нас есть система плагинов в службе WCF, которая проверяет библиотеки, помещенные в папку bin, на наличие определенных атрибутов уровня сборки и загружает их. Это позволяет настраивать определенные сервисные вызовы в зависимости от того, какой клиент делает вызов. Это отлично работает большую часть времени. Однако иногда кажется, что dll теряется, что заставляет службу возвращаться к реализации по умолчанию для каждого клиента. До сих пор решение заключалось в том, чтобы просто переместить файл dll из папки bin и обратно. Это заставляет asp.net забрать файл, и настройки снова начинают работать.

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

Изменить: проблема сформулирована более четко

Наши сервисы используют фабрику сервисов для предоставления пользовательских реализаций в зависимости от того, какой клиент вызывает код. Если пользовательской реализации нет, мы выдаем реализацию по умолчанию. Мы используем GetAssemblies для проверки сборок, которые украшены атрибутом, определяющим их как пользовательскую реализацию и связывающим их с клиентом. Проблема в том, что GetAssemblies перестает возвращать пользовательскую сборку клиента, даже если библиотека остается в папке bin. Перемещение dll из корзины и обратно в нее решит проблему примерно на неделю, пока она не повторится.


person Timothy Strimple    schedule 13.03.2010    source источник
comment
что больше не использует пользовательскую реализацию? Ваш код? Вы имеете в виду, что вызов GetAssemblies() не возвращает сборки, которые, по вашему мнению, он должен возвращать? Проблема не очень четко описана.   -  person Cheeso    schedule 23.03.2010
comment
Наши сервисы используют фабрику сервисов для предоставления пользовательских реализаций в зависимости от того, какой клиент вызывает код. Если пользовательской реализации нет, мы выдаем реализацию по умолчанию. Мы используем GetAssemblies для проверки сборок, украшенных атрибутом, определяющим их как пользовательскую реализацию и связывающим их с клиентом. Проблема в том, что GetAssemblies перестает возвращать пользовательскую сборку клиента, даже если библиотека остается в папке bin. Перемещение dll из корзины и обратно в нее решит проблему примерно на неделю, пока она не повторится.   -  person Timothy Strimple    schedule 24.03.2010
comment
вы получаете сообщение об ошибке или предупреждение в журналах событий? Кроме того, какое-либо антивирусное программное обеспечение работает на этом устройстве?   -  person SoftwareGeek    schedule 25.03.2010


Ответы (5)


Проблема, с которой вы столкнулись, должна быть связана с автоматической перезапуском домена приложения. Очевидно, перезапуск домена приложения ведет себя иначе, чем настоящий перезапуск. При повторном использовании он будет загружать только те dll, которые явно указаны и загружаются по мере необходимости. См. эту ссылку http://www.chrisvandesteeg.nl/2006/06/15/appdomain-recycle-other-from-real-restart/

Тот факт, что GetAssemblies вернет вам только ту сборку, которая в данный момент загружена в домен приложения, может объяснить аномалию, которую вы получаете с вашей программой. Чтобы быть в безопасности, если вы имеете дело с библиотекой типов плагинов, вы всегда должны сканировать файлы плагинов (dll) и загружать их явно с помощью Assembly.LoadFrom. Другой альтернативой является размещение ваших служб WCF на внешнем пользовательском узле, таком как оконная служба, чтобы срок службы узла не подпадал под действие политики повторного использования IIS.

Прочитайте это для получения дополнительной информации об утилизации домена приложения http://blogs.msdn.com/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain.-recycles.aspx

person Fadrian Sudaman    schedule 26.03.2010
comment
Варианта принятия больше нет. Это был бы ответ, который я бы принял. - person Timothy Strimple; 31.03.2010
comment
Жаль, что я не получил награду :p - person Fadrian Sudaman; 01.04.2010

Как загружаете сборки? Следующий вопрос... почему? Сборки в каталоге bin должны автоматически загружаться и быть доступными для приложений ASP.NET, которые на них ссылаются. Возможно, вы получаете здесь какой-то конфликт... т. е. доступ запрещен, потому что какой-то другой поток/процесс имеет открытый дескриптор сборки. Извините, что так расплывчато, но это единственное, что сразу приходит на ум. Вы можете потенциально использовать FileMon или аналогичный инструмент, чтобы проверить это.

Кроме того... что именно вы подразумеваете под "потерять" DLL? Вы вызываете какой-то конкретный метод, чтобы найти его, и он терпит неудачу? В чем ошибка? Вы проверили средство просмотра событий на наличие необработанных исключений?

person Bryan    schedule 14.03.2010
comment
Мы вызываем AppDomain.CurrentDomain.GetAssemblies() и проверяем их, чтобы увидеть, есть ли у них правильный атрибут. Если да, то мы используем его вместо реализации по умолчанию. Под потерями я подразумеваю, что он больше не использует пользовательскую реализацию, а вместо этого использует стандартную. - person Timothy Strimple; 14.03.2010
comment
что больше не использует пользовательскую реализацию? Ваш код? Вы имеете в виду, что вызов GetAssemblies() не возвращает сборки, которые, по вашему мнению, он должен возвращать? Проблема не очень четко описана. - person Cheeso; 23.03.2010
comment
Я думал, что сборки загружаются лениво. У нас было приложение, которое требовало некоторых подсказок относительно того, на какие сборки смотреть, потому что основное приложение не имело прямой ссылки на него. - person Ant; 24.03.2010
comment
Он использует REFLECTION для динамической загрузки сборок. - person SoftwareGeek; 25.03.2010

GetAssemblies возвращает только список уже загруженных сборок. Если вы не использовали тип из этой сборки, он еще не загружен. Вам нужно использовать Assembly.Load, чтобы загрузить нужную сборку с диска; сборки в папке /bin не загружаются автоматически в домен приложения.

Кроме того, вы можете использовать Managed Extensibility Framework (MEF), она была разработана специально для обработки функциональность, о которой вы говорите.

person Robert C. Barth    schedule 25.03.2010

... замена сборки в каталоге \bin приведет к новой пакетной компиляции этого каталога.

http://msdn.microsoft.com/en-us/library/5dws599a(VS.71).aspx

У вас есть код инициализации в Application_Start внутри global.aspx?

person Raj Kaimal    schedule 26.03.2010

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

person emalamisura    schedule 26.03.2010