Веб-роль не запускается, поскольку зависимая сборка не может быть загружена

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

Мой проект webrole зависит от AssmeblyA, который, в свою очередь, зависит от AssemblyB, Version=1.0. Веб-роль также напрямую зависит от AssemblyB, но Version=2.0. (все это происходит из разных пакетов NuGet, над которыми я не контролирую).

В итоге AssemblyB, Version=2.0 копируется в папку \Bin. Сам веб-сайт работает правильно, потому что в Web.config есть перенаправление привязки для AssemblyB к версии = 2.0 (которое автоматически помещается туда клиентом nuget).

Однако когда веб-роль развертывается в Azure, она не запускается, так как не удается загрузить AssemblyB версии = 1.0.

Я подозреваю, что это связано с тем, что веб-роль сначала загружается из каталога Approot, где web.config не действует. Я также обнаружил, что могу обойти эту проблему, создав app.config для веб-роли и продублировав там все переадресации привязок. Пока это работает, поддерживать такую ​​настройку не очень удобно.

Кто-нибудь знает, является ли это известной проблемой с веб-ролями Azure?

Пробовал с Azure SDk 2.4 и 2.5.1, все пакеты nuget azure обновлены, никакого пользовательского кода запуска.

Обновление: вот исключение, полученное с помощью IntelliTrace:

Не удалось загрузить точку входа роли из-за следующих исключений: -- System.IO.FileLoadException:

Не удалось загрузить файл или сборку «Microsoft.Owin, версия = 3.0.0.0, культура = нейтральная, PublicKeyToken = 31bf3856ad364e35» или одну из ее зависимостей. Определение манифеста обнаруженной сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040) Имя файла: «Microsoft.Owin, версия = 3.0.0.0, культура = нейтральная, PublicKeyToken = 31bf3856ad364e35»

А вот трассировка стека:

CommonLanguageRuntimeLibrary!System.Reflection.RuntimeModule.GetTypes() 
CommonLanguageRuntimeLibrary!System.Reflection.Assembly.GetTypes()  
Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetRoleEntryPoint(System.Reflection.Assembly entryPointAssembly = {System.Reflection.RuntimeAssembly})  
Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CreateRoleEntryPoint(Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleType roleTypeEnum = IISWeb)    
Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleType roleTypeEnum = IISWeb)  
Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRole(Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleType roleType = IISWeb)  
Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.AnonymousMethod()   
CommonLanguageRuntimeLibrary!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext = {unknown}, System.Threading.ContextCallback callback = {unknown}, object state = {unknown}, bool preserveSyncCtx = {unknown})   
CommonLanguageRuntimeLibrary!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext = {unknown}, System.Threading.ContextCallback callback = {unknown}, object state = {unknown}, bool preserveSyncCtx = {unknown})   
CommonLanguageRuntimeLibrary!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext = {unknown}, System.Threading.ContextCallback callback = {unknown}, object state = {unknown}) 
CommonLanguageRuntimeLibrary!System.Threading.ThreadHelper.ThreadStart()

Ошибка возникает из-за того, что мой проект веб-роли зависит от версии Owin = 3.0.1.0, но другая DLL (которую я получаю через nuget) зависит от версии Owin = 3.0.0.0. Отсюда явное несоответствие.

Таким образом, похоже, что среда выполнения службы все еще загружает мои сборки в WaIISHost.exe, просто чтобы проверить, есть ли у меня RoleEntryPoint или нет (у меня нет). Как и раньше, как только я кладу myassembly.dll.config со скопированными из web.config привязками редиректов в E:\approot\bin, все запускается корректно.


person dennis    schedule 28.03.2015    source источник


Ответы (2)


Можете ли вы уточнить, что именно вы ищете? Вы предоставляете ответ в своем вопросе (добавляете перенаправления в app.config) и предоставляете ссылку на объяснение в одном из ваших комментариев (http://blogs.msdn.com/b/avkashchauhan/архив/2011/01/24/dissection-of-a-windows-azure-sdk-1-3-based-asp-net-web-role-in-full-iis-mode-amp-hwc.aspx).

Я могу подтвердить, что то, что вы видите, является ожидаемым поведением, и ваше решение по добавлению перенаправления привязки в app.config правильное.

Другим потенциальным решением может быть изменение вашего кода RoleEntrypoint (например, WebRole.cs), чтобы он не зависел от AssemblyB, версия = 1.0. Что бы вы ни делали в классе RoleEntrypoint, можно ли это сделать из Application_Start, чтобы оно выполнялось в IIS?

person kwill    schedule 29.03.2015
comment
Он упоминает, что в WebRole нет пользовательского кода запуска, поэтому я думаю, что он может это сделать. Это то, что я пытался выяснить с помощью предоставленных шагов, если это проблема роли или IIS. Думаю, я должен был считать само собой разумеющимся, что неудача при запуске означает, что моя роль вообще не начинается. Виноват. Спасибо за прыжки в Кевина. Я удалю свой ответ, поскольку он указывает на неправильное направление. - person Panos; 29.03.2015
comment
Ну, это не совсем ответ (не решение). Это просто грязный обходной путь. Я добавил еще несколько деталей - подробное сообщение об ошибке и трассировку стека. Возможно, теперь меня интересует, почему рантайм службы автоматически не подхватывает переадресацию привязки из web.config? Я никогда не видел никаких рекомендаций по поддержке как app.config, так и web.config для проектов веб-ролей и дублированию всех перенаправлений привязок в обоих местах. Это только кажется ненужным. - person dennis; 30.03.2015
comment
Я имел в виду, конечно, что мой собственный ответ не является ответом :) - person dennis; 30.03.2015
comment
ServiceRuntime загружает библиотеку DLL точки входа вашей роли и отражает все классы, пока не найдет тот, который является производным от RoleEntryPoint. Если вы ничего не делаете в своей точке входа роли, вы можете просто создать фиктивную точку входа, которая не имеет ссылок на AssemblyB. Тогда вам не понадобится перенаправление привязки в app.config, поскольку Azure загрузит вашу фиктивную точку входа в WaIISHost.exe. - person kwill; 30.03.2015
comment
Не уверен, как это должно работать. Если вы предлагаете создать фиктивную точку входа в том же проекте веб-роли, это не поможет, потому что в этой dll все еще есть ссылка на AssemblyB. Если вы имеете в виду фиктивную точку входа в другом проекте, то, ну, это будет другая роль, и моя начальная роль все равно не загрузится. Я не могу удалить ссылку на AssemblyB, V = 2.0, потому что она также является зависимостью nuget. - person dennis; 31.03.2015
comment
Теперь, когда я снова смотрю на эту проблему, не кажется ли вам, что это ошибка в Azure? Наличие зависимостей от разных версий сборок и использование перенаправления привязки теперь является очень распространенным случаем из-за nuget. Не все авторы регулярно обновляют свои пакеты, поэтому легко получить перенаправление привязки. Тогда вы находитесь в ситуации, когда все работает локально под полным IIS, затем вы развертываете веб-роль в Azure, и она не запускается без уважительной причины. Я думаю, когда вы, ребята, ищете точки входа в веб-ролях, вам следует заглянуть в web.config для привязки перенаправлений. - person dennis; 31.03.2015

Группа поддержки Azure предоставляет AzureTools для решения подобных проблем. AzureTools включает и выключает ведение журнала Fusion и легко собирает журналы Azure.

Как только вы включите ведение журнала Fusion, вы сможете получить больше информации об отсутствующей сборке.

http://blogs.msdn.com/b/kwill/archive/2013/08/26/azuretools-the-diagnostic-utility-used-by-the-windows-azure-developer-support-team.aspx

person Takekazu Omi    schedule 29.03.2015
comment
Спасибо, я кажется понял, как происходит ошибка. Мой вопрос скорее в том, почему среда выполнения службы Azure загружает мои DLL, если у меня нет точки входа в роль, и даже если она ее загружает, почему она не использует перенаправления привязки из web.config. - person dennis; 30.03.2015