Whilst building the CloudCuckoo module, I used a neat trick to register my custom VPP on-the-fly by using an attribute flag to mark it as an EPiServer plugin. This would cause EPiServer to find it and intialise it when I first hit the EPiServer site. This worked fine on my machine and some others, but I was finding that on one specific machine it wasn't firing properly. EPiServer was calling it to initialise it, but the problem was when I tried to access the HttpContext. In a nutshell, for some reason when this machine fired up the plugin to initialise it, it was losing or not passing in the HTTP context. Typically, this would happen if there was a funny AppDomain issue or if something was being recycled, but all the configuration looked fine. The code causing the problem is below:
1: if (HttpContext.Current == null)
2: {
3: // Running from the scheduler, skip registration
4:
5: System.Diagnostics.Debug.Write("VppInitializer called without HttpContext. Exiting");
6:
7: return;
8:
9: }
10:
11: // Register
12:
13: Assembly lateBoundAssembly = System.Reflection.Assembly.LoadFrom(HttpContext.Current.Server.MapPath(@"\bin\BusinessDecision.CloudCuckoo.dll"));
When I ran DebugView I could see that the plugin was bombing out due to no HTTP context and never getting to the registration. After trying for a while to get the HTTP context and failing, I decided to tweak things around. First I changed the way the plugin was detected to using inheritance, as described in this post by Allan Thræn. That worked insofar that it did exactly the same thing - but I preferred to use inheritance so left it in there anyway :) I then decided to eliminate the need for the HTTP context at all. The only reason it was there was to get the path using Server.MapPath, but it occurred to me that given my Single-Assembly-Plugin approach, all I had to do was grab the codebase property of the current assembly! That had the added advantage that I was no longer limiting the DLL to having to reside in the BIN folder. In theory it could now even go in the GAC. The updated code looks like this:
1: Debug.Write("VppInitializerX Loading CloudCuckoo VPP from: " + typeof(VppInitializerX).Assembly.CodeBase);
2:
3: // now binds without using HttpContext
4:
5: Assembly lateBoundAssembly = System.Reflection.Assembly.LoadFrom(typeof(VppInitializerX).Assembly.CodeBase);
As you can see, this code is much cleaner and, most importantly, it works on that machine that was being problemmatical. This is probably a good thing to bear in mind for any EPiServer plugins called in this way - using HTTP context might be risky.