Daily .Net Feeds - ASP.Net 2.0 - Advanced - Day 14

Hi Everyone,

Welcome back!!!

Yeah, we skipped a few days again, just got a bit busy with my cases. As mentioned earlier, today we will be taking up the discussion about ASP.Net 2.0 Build Providers.

Build Providers:

In ASP.NET 1.x, only a few file types are dynamically compiled into assemblies—ASP.NET pages, user controls, ASP.NET Web services, and custom HTTP handlers. In ASP.NET 2.0, compilation model is extended to virtually any file type that you use in your application. In ASP.NET 2.0, commonly used file types are bound to a special breed of component—the build provider—which communicates with the ASP.NET infrastructure and provides the code representation of the contents of the specified file. Hence the build provider registered to process .aspx files will parse the .aspx markup and build a class according to the rules we identified in the session for "Day 5". This class will then be transformed into an assembly with a given scope.

ASP.NET developers are familiar with this model. The great news is that ASP.NET 2.0 applies this same model to a wide range of file types, such as class files (.cs, .vb), resource files (.resx), Web service references (.wsdl), typed DataSet (.xsd), themes, and so on. Certain file types undergo a runtime transformation process when dropped in some reserved folders. This transformation is driven by native build providers with the same internal architecture and mechanics of providers that build ASP.NET pages.

Essentially, a build provider is a component that can plug into the ASP.NET compilation system and provide custom compilation support for some file types. Build providers can automatically generate an appropriate proxy class by interpreting at compile time the contents of the source file. A build provider generates compilable code and keeps it in sync with the source file; as the source file changes, the build provider kicks in again and updates everything. To solidify this abstract discussion :-) of build providers let's take a look at the following excerpt from the default configuration file. It illustrates the built-in bindings between file types and native build providers:

<compilation>

    <buildProviders>

        <add extension=".aspx"

            type="System.Web.Compilation.PageBuildProvider" />

        <add extension=".ascx"

            type="System.Web.Compilation.UserControlBuildProvider" />

        <add extension=".master"

            type="System.Web.Compilation.MasterPageBuildProvider" />

        <add extension=".asmx"

            type="System.Web.Compilation.WebServiceBuildProvider" />

        <add extension=".ashx"

            type="System.Web.Compilation.WebHandlerBuildProvider" />

        <add extension=".resx"

            type="System.Web.Compilation.ResXBuildProvider" />

        <add extension=".resources"

            type="System.Web.Compilation.ResourcesBuildProvider" />

        <add extension=".wsdl"

            type="System.Web.Compilation.WsdlBuildProvider" />

        <add extension=".xsd"

            type="System.Web.Compilation.XsdBuildProvider" />

        <add extension=".js"

            type="System.Web.Compilation.ForceCopyBuildProvider" />

    </buildProviders>

</compilation>

Note: All these build providers are nonpublic, internal classes defined in the System.Web.Compilation namespace inside the system.web assembly. All these classes derive from one common root—the BuildProvider class.

We'll get into the details of BuildProviders in a moment. For now, the following figure shows the conceptual layout of the ASP.NET compilation model.

Conceptual Layout of ASP.Net Compilation System

The host environment receives input from external components—a client (for example, Visual Studio 2005 or precompilation utilities) using the ClientBuildManager API or the ASP.NET pipeline—and activates the build manager. The build manager, in turn, invokes the build provider in charge of the resource. When the proxy class has been generated, the assembly builder kicks in to compile the source.

Note: Build providers are an important building block in the overall ASP.NET infrastructure, but they are certainly not the kind of component you'll have to tinker with every day. You should know that they exist and how they work. In the end, however, you'll rarely run into them unless you need to adjust the way certain files are processed by ASP.NET.

Build providers kick in during compilation, but compilation can occur for two different reasons—to service a user request at run time and to precompile an application. A file for which a build provider is registered is passed to the provider and processed. What happens next depends on the build provider logic. Application files mapped to a .NET language (for example, .cs or .vb files) are passed to the respective compilers and processed, but they are not deployed. Files that are bound neither to compilers nor build providers are ignored during the compilation step. The precompilation for the deployment mechanism, though, copies them to the final layout.

There are two points left open tough – a couple exceptions: What happens with .js files? And what if you want to exclude some files from deployment? ForceCopyBuildProvider addresses the former, while IgnoreFileBuildProvider is used for the latter.

The ForceCopyBuildProvider Provider:

Specifically designed for .js files, this provider ensures that .js files are always copied during the precompilation for deployment. The issue is that .js is the extension of a standard .NET language—JScript. According to the rules we just outlined, Javascript files wouldn't be deployed. However, a .js file is often a client-side file, the lack of which can compromise an application. To avoid that, the .js extension is bound to ForceCopyBuildProvider, and .js files are then always copied when you deploy your Web site through the Copy Web Site operation in Visual Studio 2005.

The IgnoreFileBuildProvider Provider:

Whereas ForceCopyBuildProvider always copies files, the IgnoreFileBuild provider always excludes files of a certain type from participating in any compiling or publishing operation. The ignore-file provider is particularly useful for development-only files you maintain for internal purposes but that have no reasons for being deployed—for example, a Microsoft Office Word document, Microsoft Office Visio diagrams, and so on. Enter the following script in your web.config file to let the compilation system ignore .doc files.

<compilation>

    <buildProviders>

        <add extension=".doc"

            type="System.Web.Compilation.IgnoreFileBuildProvider" />

    </buildProviders>

</compilation>

Architecting a Custom Build Provider:

Build providers are a constituent part of the compilation machinery and participate in build operations regardless of the starter—be it Visual Studio 2005 or the ASP.NET runtime. As a developer, you can implement your own provider to add custom semantics to ASP.NET compilation.

An interesting example consists of adding logic to process files with a given extension whose contents represent a mapping with one or more database tables. The provider could then dynamically generate strongly typed classes to render columns in the table. Classes will be generated any time one of these files is added to the project. Nicely enough, build providers also get you full IntelliSense support within Visual Studio 2005.

Note:

Have you ever wondered what the magic is that allows Visual Studio 2005 to recognize control properties through IntelliSense on the code-behind class of an .aspx page? In ASP.NET 1.x, Visual Studio .NET 2003 created ad hoc members to represent controls in protected regions so that the class was complete for a .NET reflection analysis. In ASP.NET 2.0, members that represent server controls are created at compile time thanks to the mechanism of partial classes. So how can IntelliSense work correctly on code files?

The answer is that Visual Studio 2005 has the .aspx build provider generate the dynamic source code of the class with all missing declarations. The resulting assembly is loaded in the Visual Studio 2005 process; the resulting type of the page is scanned through reflection to populate the IntelliSense drop-down lists. So the process we studied on "Day 5" about aspx markup being parsed to generate corresponding partial class definition is continuously happening as we type code. :-)

That's it for today. Thanks for joining!!! See you tomorrow. Tomorrow we will discuss an extremely interesting new feature of ASP.Net 2.0 – Virtual Path Provider. Post that in the oncoming sessions we will be delving into HTTP Handlers and Modules.

Thanks,

Sukesh Khare
Coordinator Daily .Net Feed Program