Three Hidden Extensibility Gems in ASP.NET 4

ASP.NET 4 introduces a few new extensibility APIs that live the hermit lifestyle away from the public eye. They’re not exactly hidden - they are well documented on MSDN - but they aren’t well publicized. It’s about time we shine a spotlight on them.

PreApplicationStartMethodAttribute

This new attribute allows you to have code run way early in the ASP.NET pipeline as an application starts up. I mean way early, even before Application_Start.

This happens to also be before code in your App_code folder (assuming you have any code in there) has been compiled.

To use this attribute, create a class library and add this attribute as an assembly level attribute. A common place to add this would be in the AssemblyInfo.cs class within the Properties folder.

Here’s an example:

[assembly: PreApplicationStartMethod(
  typeof(SomeClassLib.Initializer), "Initialize")]

Note that I specified a type and a method. That method needs to be a public static void method with no arguments. Now, any ASP.NET website that references this assembly will call the Initialize method when the application is about to start, giving this method a chance to do perform some early initialization.

public static class Initializer
{
  public static void Initialize() { 
    // Whatever can we do here?
  }
}

The primary use of this feature is to enable tasks that can’t be done within Application_Start because it’s too late. For example, registering build providers and adding assembly references.

Which leads us to…

BuildProvider.RegisterBuildProvider

As you might guess, if one of the key scenarios for the previously mentioned feature is to allow registering build providers, well ASP.NET better darn well allow you to register them programmatically.

Prior to ASP.NET 4, the only way to register a custom build provider was via the <buildproviders> node within web.config. But now, you can register them programmatically via a call to the new BuildProvider.RegisterBuildProvider method.

BuildProvider.RegisterBuildProvider(".foo", typeof(MyBuildProvider));

Combining the PreApplicationStartMethodAttribute with this method call means that installing a build provider can be done in one step -simply reference the assembly with the build provider and the assembly can register it for you. Whereas before, you would have to reference the assembly and then muck around with web.config.

I think I speak for us all when I say “Yay! Less junk in my web.config trunk!”

BuildManager.AddReferencedAssembly

Another new method added in ASP.NET 4 allows adding an assembly to the application’s list of referenced assemblies. This is equivalent to adding an assembly to the <assemblies> section of web.config.

As you might guess, this comes in handy when registering a custom build provider. It allows you to programmatically add references to assemblies that may be needed by your build provider.

Oh, and it’s yet another way to reduce the size of your web.config file. Who doesn’t love that? :)

What others have said

Requesting Gravatar... Chris Cavanagh May 16, 2010 11:26 AM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Phil - Any issues with implementing the PreApplicationStartMethod directly in the web app that uses it? (rather than a separate assembly). I'm already doing this successfully, but could separate it if necessary (weird side effects etc). Thanks!
Requesting Gravatar... Chris Cavanagh May 16, 2010 11:28 AM
# re: Three Hidden Extensibility Gems in ASP.NET 4
To clarify... Meant to say "if there were weird side effects". Currently seems to be behaving itself :) (note if debugging through IIS rather than Cassini it can look like the method isn't getting called (breakpoints don't get hit), but it does actually work fine).
Requesting Gravatar... Sergio Pereira May 16, 2010 10:13 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Does VS also run these initializers? I mean, if I add an assembly reference like that, will VS recognize its types in an .aspx file for example? In the past I had problems when I did similar things (like adding a virtual path provider) and confusing VS' designers.
Requesting Gravatar... Bret Ferrier May 16, 2010 11:35 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Just one question. Are there any examples off the top of your head that you can think of where people are using these new .Net 4.0 features?
Requesting Gravatar... René Kuss May 17, 2010 2:07 AM
# re: Three Hidden Extensibility Gems in ASP.NET 4
I'm using the PreApplicationStartMethodAttribute to configure a di container. It works without any problems. No more bogus configuration code in global.asax.
Requesting Gravatar... haacked May 17, 2010 5:21 AM
# re: Three Hidden Extensibility Gems in ASP.NET 4
@Chris there's nothing special about a web app as far as ASP.NET is concerned at runtime. It gets compiled as just another assembly. So I can't imagine there'd be any weird side effects.

@Bret One obvious one would be to register a custom build provider. For example, Subsonic used to ship with a build provider. With this approach, manual configuration in web.config would've been unnecessary.

You'll see more examples coming from our team in the future.
Requesting Gravatar... Thanigainathan May 17, 2010 5:13 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Hi,

BuildManager.AddReferencedAssembly will register a assembly at runtime. So I cannot really access the classes inside them during the design time right ?

Please explain this.

Thanks,
Thanigainathan.S
Requesting Gravatar... haacked May 18, 2010 12:30 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
@Thanigainathan that's right. If you want it at design time, just add a project reference.
Requesting Gravatar... Ben May 18, 2010 11:53 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Would it be possible to use that RegisterBuildProvider method to minify all of your .js files? Just curious...
Requesting Gravatar... Joop May 20, 2010 4:47 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Strange thing happening to me with the PreApplicationStartMethod Attribute. I did implement it in my latest project. In the AssemblyInfo.cs

[code]
[assembly: PreApplicationStartMethod(typeof(MyAssembly.Initializer), "Initialize")]

namespace MyAssembly
{
public static class Initializer
{
public static void Initialize()
{
TranslationKeys.Initialize();
}
}
}
[/code]

When I rebuild my application and load it in the browser I get the following error:
[blockquote]
The method specified by the PreApplicationStartMethodAttribute on assembly 'MyWebApp, Version=0.0.1.0, Culture=neutral, PublicKeyToken=null' cannot be resolved. Type: 'MyAssembly.Initializer', MethodName: 'Initialize'. Verify that the type is public and the method is public and static (Shared in Visual Basic).[/blockquote]
Requesting Gravatar... PeanutButterLou Jun 16, 2010 7:14 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
YESSSSSSSSS!!!!! Oh man was doing all this auto-install stuff with the assembly level attributes and what-not a pain to get working before this attribute came to be. vnice.
Requesting Gravatar... Vi Aug 21, 2010 2:39 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Can the combination of these three gems be used to enable custom build providers for Web Application projects?

Vi
Requesting Gravatar... Interactive Intelligence Jan 31, 2011 10:38 AM
# re: Three Hidden Extensibility Gems in ASP.NET 4
Never knew these extensibility APIs existed- why is it you think these aren’t better publicized? I love the fact that you can register a custom build provider programmatically with this API, plus the efficiency of installing the build provider in one step! I see smaller web.config files in the future with this gem...everyone has to love that!
Requesting Gravatar... Per Samuelsson Aug 09, 2011 7:06 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
@Phil,

Thanks for sharing your insight.

@all,

FWIW, I was hoping this could be a big help for a problem we have, relating to assembly reference resolving in ASP.NET, but unfortunally, we were not able to use it since (as it seems) the initializer you register using the PreApplicationStartMethodAttribute is never fired if applied on an assembly residing in the GAC. Which is the case in our design.

Just thought I'd share this.
Requesting Gravatar... Frode Feb 23, 2012 6:34 PM
# re: Three Hidden Extensibility Gems in ASP.NET 4
I've been using the AppInitialize technique lately and wanted to try out the PreApplicationStartMethod attribute.
My initialization code reads a custom config section and this failed with a ConfigurationErrorsException using PreApplicationStartMethod.
"An error occurred creating the configuration section handler for testproject: This method cannot be called during the application's pre-start initialization stage. ".
Is there another attribute that can trigger my initalization code at a later moment? Like AppInitialize?

What do you have to say?

(will show your gravatar)
Please add 5 and 7 and type the answer here: