ASP.NET 2.0 Build Providers
April 26, 2005
Its probably fair to say that the ASP.NET team has pushed the envelope as far as web-application compilation models go with the upcoming release of ASP.NET 2.0. Under the covers ASP.NET leverages “build providers” to take the various common ASP.NET files *.aspx, *.ascx and Web.config (to name but a few) and produces source code that can be compiled and executed.
For the most part you can build applications an be blissfully unaware of this feature but if you want to get invited to all the cool parties you should probably get familiar with build providers. A build provider is a class that derives from the System.Web.Compilation.BuildProvider base class, out of the box ASP.NET 2.0 comes with the following (internal) build providers.
- ApplicationBrowserCapabilitiesBuildProvider
- BaseResourcesBuildProvider
- ResourcesBuildProvider
- ResXBuildProvider
- ForceCopyBuildProvider
- IgnoreFileBuildProvider
- InternalBuildProvider
- BaseTemplateBuildProvider
- ApplicationBuildProvider
- PageThemeBuildProvider
- GlobalPageThemeBuildProvider
- TemplateControlBuildProvider
- PageBuildProvider
- UserControlBuildProvider
- MasterPageBuildProvider
- SimpleHandlerBuildProvider
- WebHandlerBuildProvider
- WebServiceBuildProvider
- SourceFileBuildProvider
- ProfileBuildProvider
- WebReferencesBuildProvider
- WsdlBuildProvider
- XsdBuildProvider
As you can see there isn’t much that build providers don’t touch and if you look closely you can tell a lot about the architectural decisions that Microsoft made about certain features (notice what the MasterPageBuildProvider derives from). Build providers really support two things on top of the usual runtime compilation behaviour. First, they are used by the “aspnet_compile.exe” utility to generate the pre-compiled version of a site – this feature would have had to have been in the top five requested features by ASP.NET developers so it was great to see that they got it to work.
The second place where build providers work is at design time to ensure that the intellisense engine has type information to provide developers as they are cutting code. Have you ever wondered how VS2005 knows what properties are exposed via the code-behind file associated with a web-control when you drop it onto your web-form?
Now that we know how build providers are used out of the box lets see if we can practice our own form of ASP.NET voodoo and get them working for us. What I am going to show you is how to create your own build provider which reads a XML files located in the App_Code directory that have the *.exception extension and compiles up a custom exception class that can then be used in code. What use is that? Well thats not the point is it 
The first thing that you need to do is create a custom build provider, you can see the code I used below.
We will get to the helper code in a minute, but briefly we can see that this class derives from BuildProvider and overrides the GenerateCode(…) method. The GenerateCode(…) method takes an AssemblyBuilder instance – but don’t be confused, this is not the AssemblyBuilder from the System.Reflection.Emit namespace, this is one specifically designed for the build providers in ASP.NET and it lives in the System.Web.Compilation namespace.
The idea is that we use CodeDom to generate an abstract representation of the code that represents the contents of the *.exception file and pass that to the AssemblyBuilder which then compiles it up into an assembly along with any other code that is being dealt with at the time. What code we generate is completely up to us but typically you would want to take some input from a file with an extension that the build provider is associated with.
Fortunately the BuildProvider base-class has a number of helper methods to make it easy to read in that content as the listing of helper methods show.
The key in the listing above is the call to the BuildProvider.OpenStream() method which allows us to return an open stream to the underlying file that the BuildProvider is working with. You also have access to the BuildProvider.VirtualPath property which gives the site relative path to the file being built. When you first work with the API you might be tempted to try and call MapPath to resolve that to a physical file, however at this point in the pages’ lifecycle you don’t have access to the HttpContext which is where the OpenStream method comes in.
Once you have the BuildProvider written you need to associate it with the file extension that you want to work with, you do that by registering it in the <buildProviders /> section of the Web.config file.
Here you can see that this build provider is associated with the App_Code directory (Code) and is mapped to the *.exception extension (.exception) along with a qualified reference to the BuildProvider class. Once all of this is in place, you can drop a file into the App_Code directory, my file looked like this.
As soon as you save that file and build the ExceptionBuildProvider will kick into action then you will be able to code against the exception class generated as if it was just code you had written yourself.
If you want a bit of a head start or some code to look at you can download my demo code from Project Distributor.
April 26, 2005 at 12:00 am
damn Mitch you’ve done it again… I’m blown away. Thanks buddy.
The implications for this are staggering.
April 26, 2005 at 12:00 am
Yeah – but Paul, you’d like anything with the words CodeDom, ASP.NET and voodoo in the same block of text
August 30, 2005 at 12:00 am
Does this work only in web applications, or can I use this technique in winforms applications too?
August 30, 2005 at 12:00 am
Hi Dirk,
I’m afraid not. Its part of the ASP.NET infrastructure.
August 30, 2005 at 12:00 am
Hi Dirk,
I’m afraid not. Its part of the ASP.NET infrastructure.
August 31, 2005 at 12:00 am
Pity – but thanks anyway.
September 21, 2006 at 6:30 am
[...] I found a reference on Scott Watermasysk's blog about a project called "SubSonic" on CodePlex. I watched the video demo for the project and I was very impressed with quite a few things here.First off, the DAL that SubSonic generates is top notch. I think it's very flexible and a lot of programmers will like the flexibility that it provides. This is not what caught my eye, though.SubSonic has the ability to generate code on the fly at compile-time via something called a BuildProvider (I'd never heard of this). Basically, you just specify this custom BuildProvider in the web.config of your ASP.NET project and at design and/or compile time, the BuildProvider will connect to the specified database, and generate SubSonic's DAL model.Now here's where I got excited. SubSonic is great, but it limits you to using its own DAL template (which is again, the bee's knees), but what if you like the Wilson O/RMapper? Maybe you like .netTiers for your DALs. Wouldn't it be great to use a BuildProvider to leverage CodeSmith? Yes.So I wrote one.This gave me the chance to really learn about BuildProviders and also to take a look at the CodeSmith SDK while I was at it. I'd never used it before, but it was really easy to use.To use it, you simply add the BuildProvider to the web.config of your choice.I've specified that for this website, any files named with the .example extension (I know, original right?) should be compiled with the custom BuildProvider.To create the file to be compiled by the BuildProvider, simply create a text file with the aforementioned extension and insert lines with a Codesmith template file and an associated settings file (separated by the pipe, "|", symbol) in this form:<Codesmith Template File>|<Settings For This Template> Example:c:MyCodesmithTemplate.cst|c:MyCodesmithTemplateSettings.xmlTo generate the settings file, open your template in Codesmith explorer, fill in the appropriate fields and then click "Save Property Set XML".Armed with this and the providers in the right spot, you should get almost immediate intellisense information back for the types that were just generated.I'm including the provider and a sample web project so that you can see how this works. I hope at the very least this will help someone understand BuildProviders. They are interesting and very powerful tools if used correctly.Some caviats:BuildProviders cannot function in Medium TrustI cannot provide a copy of the Codesmith assemblies with this project. You can get your own eval copy of Codesmith by visiting http://www.codesmithtools.com.If you do use an eval copy of Codesmith with this, you will get a Codesmith nag screen every time you compile. You have been warned. (I developed this using an eval copy, so I know a bit about it.)I provide no warrantees. Use at your own risk.There are most-likely bugs. Feel free to contact me about them anytime.Download: CodesmithAddonsReferencesSubSonic CommunityMSDN BuildProvider DocumentationASP.NET 2.0 Build Providers – Mitch Denny Filed under: Programming, ASP.NET [...]
September 21, 2006 at 6:36 am
Thanks for this article. It was really helpful.
September 21, 2006 at 6:51 am
Hi Anderson,
Glad it was useful.
November 12, 2006 at 5:12 am
[...] RssBuildProvider; I’ve written about Build Providers before, in this case an RSS file is read in and it spins out a strongly-typed object model which matches the sub-item elements found in the feed. It actually does a pretty good job, I grabbed a feed from Digg and threw it in and it made sense of some of the RSS extensions that they offer. [...]
July 18, 2007 at 11:41 am
Hi Anderson,
Two images in the article are not accessible
1.http://notgartner.com/Downloads/HelperMethod.GIF
2.http://notgartner.com/Downloads/smile1.gif (doesn’t matter)
anyways, nice article
October 28, 2007 at 2:49 pm
[...] for this is called a Build Provider. The good thing is, you can create buildproviders yourself. This blogpost can get you started, a custom buildProvider is created to generate exception classes on the [...]
November 17, 2009 at 7:58 am
Here an example of how you can create DAL with ASP.NET Build Providers:
1. http://www.codeproject.com/KB/aspnet/DALComp.aspx
2. http://jbaurle.wordpress.com/2007/07/24/creating-dal-components-using-custom-aspnet-build-providers-and-compiler-techniques/
Thomsen