November 22, 2010

WebActivator / PreApplicationStartMethod

Yesterday I was totally taken aback by the tiny but excellent webactivator project. I totally had a near-magic experience, that’s when I’m almost starting to suspect something works because of tiny magic elves within the .Net runtime “just know what to do” and even though the code doesn’t seem like it’s doing the right things it’s still working.

Let me explain: WebActivator is something you will probably see more and more of the more you start to use modules from NuGet. It is a neat little dll which allows you to specify anywhere in your code that a certain method is to be called on application startup. See this example from Ninject, this class gets added to your solution when installing the ninject package with nuget:

Ignore the ninject specific stuff. The goodness that webactivator brings to the table is the first line where a usage of the webactivator attribute will result in a certain method will be called on startup.

Interested in knowing just *how* WebActivator manages to do this I looked up the sourcecode. Latest version of which is available here

as it only consists of two classes, the attribute which you can include (like ninject did) and the implementation of the logic I thought it would be easy to get a handle on this.

I’ll include the two sources here so you can see if you’re smarter than me in figuring out how this works.
Attribute:

Hmm, so basically, we declare an attribute and we have a static method which when run will track down all instances of this attribute in all dlls in the bin folder and fire the method as specified in each of those instances.

But *who* calls the static method?

I had a look in the Properties\AssemblyInfo.cs file which looks like this:

and in the bottom of that file I finally started to believe that magic little elves live within the jit-compiler and make everything fine and dandy even though it seems like the feature is using itself to start itself.

Maybe there really *are* turtles all the way down?

Have you spotted how it works yet?

I’ll give you some whitespace to think of the solution before I blurt it out and ruin your fun

WebActivator doesn’t use itself but rather a feature of the Asp.Net 4.0 runtime to start itself off. The whole motivation for WebActivator is that the feature built into Asp.Net 4.0 has a design flaw in that it only allows a single instance of the attribute within each dll, making it hard to use for NuGet scenarios where you would want to use multiple different packages each with their own startup logic independent of eachother, you would have to manually merge the logic into one place if you wanted to use the Asp.Net 4.0 implementation.

However, since WebActivator.dll is a tiny separate dll it can make use of the asp.net feature to kickstart the other dlls.

I think that I would prefer if the AssemblyInfo.cs file was a little more specific in its usage of the asp.net feature, seeing that it’s basically reimplementing it itself. Instead of relying on a using statement for System.Web, I would prefer if the attribute was declared as