Azure Web Roles + RoleShared. Grrrrr…

I had a deployment to azure failing yesterday, and I thought ‘I know what caused this. It’s a dll dependency break from upgrading to Azure SDK 2.3.’

Of course I was right.

But looking at how I was getting screwed by the new sdk switch, I felt surprised at the mechanisms involved.

Of course first I had to jump through some hoops to get remote desktop working – our logging wasn’t running either (SDK dependency), and configuring remote desktop after deployment from the portal tends to fail due to some timing issue with role restarts, so I had to configure remote desktop in the package and redeploy. Much time wasted.

Once remoted in, I could see the event viewer. (Isn’t there a decent way to see windows event logs for your web roles without logging in via remote desktop? I feel sure there must be, but I don’t know about it. Why is that?)

An unhandled exception occurred. Type: System.IO.FileLoadException Process ID: 3080
Process Name: WaIISHost
Thread ID: 5
AppDomain Unhandled Exception for role CacheExtension_IN_0
Exception: Could not load file or assembly 'Microsoft.WindowsAzure.Diagnostics, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.

Aha! I was right! I felt happy and secure. All I had to do was add some redirects to my web.config declaring assembly redirect policy to version, and then life would be good again, right? Wait… WTH? I already have this redirect in my web.config. Why doesn’t it work?!

  < assemblyIdentity name="Microsoft.WindowsAzure.ServiceRuntime" publicKeyToken="31bf3856ad364e35" culture="neutral" />
  < bindingRedirect oldVersion="" newVersion="" />
< /dependentAssembly>
< dependentAssembly>
  < assemblyIdentity name="Microsoft.WindowsAzure.Diagnostics" publicKeyToken="31bf3856ad364e35" culture="neutral" />
  < bindingRedirect oldVersion="" newVersion="" />
< /dependentAssembly>

Well it turns out, if you look at the actual call stack of the exception above, that it’s being called from my WebRole.OnStart() which is itself ultimately called from Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.<InitializeRole>b__0() - which is something that runs in a process called WAIISHost.exe, not the IIS process w3wp.exe.

So, web.config just does not apply here.

Well, I’ve seen how you fix this for worker roles though. You just add app.config in your worker role project, and it ends up in your CSPKG as MyWorkerRole.dll.config, and everything works. Do I need to add app.config to my web project? That would be silly! I try it anyway, and it doesn’t work:

In fact, I notice that what really happens is: build will copy web.config (not app.config) to bin/debug/MyWebSite.dll.config. OK. So why the heck doesn’t this work then?

Well, of course there is a problem. Somehow, cspack will not include the MyWebSite.dll.config in the output cspkg file.

So. Yeah.

OK, easiest way to solve this is just update my assembly references in our RoleShared.dll which is the one which thinks it depends on Azure SDK 2.2 so they point at Azure SDK 2.3. Of course notice the name is RoleShared. None of our other roles which we deploy with this dll yet use Azure SDK 2.3. So I’m really just punting the problem down the road. Ugh. Grrr…