Compilation






Compilation

The number of ways you can compile your code increases many times over with the release of ASP.NET 2.0. In addition to the precompiled bin directory and the delay-compiled Src attribute deployment options in ASP.NET 1.x, you can now deploy raw source files to specially named directories (like /App_Code). There is a new utility, aspnet_compiler.exe, which will precompile an entire virtual directory to create a zero-source deployment (including .aspx file content). Web Deployment Projects also has a supplemental addition to Visual Studio 2005, which provides even more alternatives for compilation and deployment. We will cover each of these new compilation features in this section.

Compilation Directories

In ASP.NET 1.0, the only way to deploy supplemental classes with your Web application locally is to compile them into an assembly and place them in the /bin directory under the virtual application root. Any assembly placed in the /bin directory of an application is shadow copied to a private directory during site compilation, and every compile that ASP.NET issues for that site includes a reference to the shadow-copied assembly. This ensures that you can replace the assembly in the /bin directory with an updated one without having to shut down the Web server. When the timestamp on a particular assembly in the /bin directory is updated (typically by replacing it with a new version), the contents of the site is recompiled with references to the new assembly (which is again shadow copied prior to reference).

This technique of deploying precompiled assemblies is still supported in ASP.NET 2.0, and depending on how you structure your site and your build process, this may still be your best option going forward. There is another option in this release, however, which is to place any source code files that you would like to have compiled and referenced by your site's other elements in the new top-level App_Code directory. In fact, there are seven new top-level folders that have special meaning in ASP.NET 2.0, as shown in Figure.

Special compilation folders in ASP.NET 2.0

Directory Name

Contents

Compilation

App_Browsers

.browser files (XML format files used to describe browser capabilities)

Each .browser file is compiled into a method in the local ApplicationBrowser-CapabilitiesFactory class that is used to populate an instance of HttpBrowser-Capabilities when needed.

App_Code

Source code files (.cs, .vb, etc.), .wsdl files, .xsd files (extensible)

Source code files are compiled into an assembly for use in your application. .wsdl files are parsed into Web service proxies and then compiled. .xsd files are parsed into strongly typed DataSet classes and then compiled.

App_Data

Database files, xml data sources, other data source files

No compilation takes place.

App_GlobalResources

Resource files (.resx and .resources)

Compiled into a resource-only assembly with global scope.

App_LocalResources

Resource files (.resx and .resources) that are associated with a particular page or user control

Compiled into a resource-only assembly for access by the associated page or user control.

App_Themes

.skin, .css, images, and other resources

Compiled into a separate assembly containing resources for a particular theme.

App_WebReferences

.wsdl, .xsd, .disco, .discomap

Generates a Web service proxy for each endpoint described.

Bin

.dll assembly files

No compilation takes place. Assemblies placed in this directory are shadow copied and referenced during all other compilations associated with the site.


Any source files placed in the App_Code folder will be compiled along with all of your pages and their codebehind files when ASP.NET processes requests for your site (or during site precompilation). This means that you now have a complete range of deployment options, ranging from placing all of your source code on the server (including utility classes, business layers, data access layers, etc.) to precompiling any subset and placing the resulting assemblies in the /bin directory (or even deploying machine-wide in the global assembly cache (GAC)). Note that the decision of where to place your code files is purely a matter of convenience and organization. There is no difference in performance between a precompiled assembly and code that is placed in the App_Code folder and compiled at request time once the compilation has taken place.[4]

[4] There can be additional overhead the first time a request is made to a site using the App_Code folder, but even this can be eliminated by precompiling the site (which we will discuss shortly).

As an example of using the App_Code folder, consider the class in Listing 1-15 that we intend to use as a data source for various pages in our site.

-15. Custom data source class for deployment in the App_Code directory

// File: MyDataSource.cs
namespace EssentialAspDotNet.Architecture
{
  public static class MyDataSource
  {
    static string[] _items =
      {"Item #1", "Item #2", "Item #3", "Item #4",
       "Item #5", "Item #6", "Item #7", "Item #8",
       "Item #9", "Item #10"};

    public static string[] GetItems()
    {
      return _items;
    }
  }
}

To deploy this file, you would manually create a directory at the root of your Web application named App_Code and place MyDataSource.cs in it. All pages (and other generated types) in your site would then have access to the compiled class implicitly. The class will be compiled as part of the request sequence in much the same way .aspx files and their codebehind files are compiled. For example, we could now rewrite our earlier data-binding example using the ObjectDataSource control to declaratively associate the GetItems method as the data source for our BulletedList as shown in Listing 1-16. Chapter 3 covers the details of the ObjectDataSource; for now, note that it can be initialized with a type name and a method name, and when associated with the DataSourceID of a data-bound control, it will bind the results of invoking the method on the object to the control prior to rendering.

-16. Simple page with declarative data binding using custom data source class

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Simple page with declarative data binding</title>
</head>
<body>
    <form id="form1" runat="server">
    <h1>Test ASP.NET 2.0 Page with declarative data binding</h1>
    <asp:BulletedList runat="server" ID="_displayList"
                      DataSourceID="_itemsDataSource" >
        <asp:ListItem>Sample Item 1</asp:ListItem>
        <asp:ListItem>Sample Item 2 ...</asp:ListItem>
    </asp:BulletedList>

    <h2 runat="server" id="_messageH2">Total number of items = xx</h2>

    <asp:ObjectDataSource runat="server" ID="_itemsDataSource"
             TypeName="EssentialAspDotNet.Architecture.MyDataSource"
             SelectMethod="GetItems" />
    </form>
</body>
</html>

Site Compilation

Perhaps the most significant addition to the process of compilation in this release is the introduction of the ASP.NET compiler. The ASP.NET compiler (aspnet_compiler.exe) gives you the ability to completely precompile an entire site, making it possible to deploy nothing but binary assemblies (even .aspx and .ascx files are precompiled). This is compelling because it eliminates any on-demand compilation when requests are made, eliminating the first post-deployment hit seen in some sites using ASP.NET 1.0. It also makes it more difficult for modifications to be made to the deployed site (since you can't just open .aspx files and change things), which can be appealing when deploying applications that you want to be changed only through a standard deployment process.

Figure shows an invocation of the aspnet_compiler.exe utility using the binary deployment option and the resulting output to a deployment directory. Note that the .aspx files present in the deployment directory are just marker files with no content. They are there to ensure that a file with the endpoint name is present if the "Check that file exists" option for the .aspx extension in an IIS application is set. The PrecompiledApp.config file is used to keep track of how the application was deployed and whether ASP.NET needs to compile any files at request time. Note that this utility is also accessible graphically through the Build | Publish Web Site menu item of Visual Studio shown in Figure.

Binary deployment with aspnet_compiler.exe


Build | Publish Web Site tool in Visual Studio 2005


In addition to the binary-only deployment model, the aspnet_compiler also supports an "updatable" deployment model, where all source code in a site is precompiled into binary assemblies, but all .aspx, .ascx, .master, .ashx, and .asax files are left intact so that changes can be made on the server. This model is possible because of the inheritance in the codebehind model so that the sibling partial classes containing control declarations can be generated and compiled independently of the actual .aspx file class definitions. To generate the "updatable" site you would use -u with the command line utility, and the resulting .aspx files would contain their original content (and not be empty marker files).

With the aspnet_compiler utility in hand, you can work on your applications without worrying about how your application will be deployed, for the most part, since any site can now be deployed in any of three ways: all source, all binary, or updatable (source code in binary and .aspx files in source), without any modification to page attributes or code files used in development. This was not possible in previous releases of ASP.NET, since you had to decide at development time whether to use the Src attribute to reference codebehind files or to precompile them and deploy the assemblies to the /bin directory. Complete binary deployment was not even an option.

Assembly Generation

Now that compilation into assemblies can happen in one of three places (explicitly by the developer, using aspnet_compiler.exe, or during request processing), understanding the mapping of files into assemblies becomes even more important. In fact, depending on how you write your pages, you can actually end up with an application that works fine when deployed as all source or all binary, but which fails to compile when deployed using the updatable switch.

The general model ASP.NET uses is to create separate assemblies for the contents of the App_Code directory as well as the global.asax file (if present), and then to compile all of the .aspx pages in each directory into a separate assembly. User controls and master pages are also compiled independently from .aspx pages. It is also possible to configure the App_Code directory to create multiple assemblies if, for example, you wanted to include both VB.NET and C# source code in a project, as you will see shortly. Figure describes which of your Web site components compile into separate assemblies based on the deployment mode you are using (note that we are ignoring the resource, theme, and browser directories since they don't contain code, although they are compiled into separate assemblies as well).

Assembly generation
 

Deployment Mode

 

All Source

All Binary

Updatable (Mixed)

What Compiles into a Unique Assembly

App_Code directory

global.asax

.ascx and associated codebehind file (separate assembly for each user control)

.master and associated codebehind file (separate assembly for each master page)

All .aspx files and their codebehind files in a given directory (separate assembly per directory)

App_Code directory

global.asax

.ascx and .master files and their associated codebehind files

All .aspx files and their codebehind files in a given directory (separate assembly per directory)

App_Code directory (D)

global.asax (R)

.ascx and .master files (R)

Codebehind files for .ascx and .master files (D)

All .aspx files in a given directory (separate assembly per directory) (R)

All codebehind files associated with .aspx files in a given directory (separate assembly per directory) (D)

When It's Compiled

Request time

Deployment time

(R) = Compiled at request time

(D) = Compiled at deployment time


There is one other twist in the assembly generation picture: You can use the -fixednames option in the aspnet_compiler to request that each .aspx file be compiled into a separate assembly whose name remains the same across different invocations of the compiler. This can be useful if you want to be able to update individual pages without modifying other assemblies on the deployment site. It can also generate a large number of assemblies for any site of significant size, so be sure to test this option before depending on it.

If this is sounding complicated, the good news is that most of the time you shouldn't have to think about which files map to separate assemblies. Your .aspx files are always compiled last, and always include references to all other assemblies generated, so typically things will just work no matter which deployment model you choose.

Customizing Assembly Generation

You have additional control in how assemblies are generated in the App_Code directory. You can use the codeSubDirectories element to further specify that subdirectories should be compiled into individual assemblies. This can be useful if you find the need to house C# and VB.NET source code in the same project, as usually they could not be placed in the same App_Code directory. Figure shows a sample layout that maps four distinct directories to different assemblies during compilation.

Creating multiple assemblies from the App_Code directory


Web Application Projects

In May of 2006, Microsoft released an addition to Visual Studio 2005 called Web Application Projects,[5] which gives you a completely different model for building Web applications with ASP.NET 2.0, one much more similar to the model developers are familiar with using Visual Studio .NET 2003. As with Web projects in Visual Studio .NET 2003, all code files in the project are built into a single assembly, which is deployed to the local /bin directory. Because Web Application Projects have a project file and are compiled like any class library project, they have complete support for all class library project settings. Figure shows a sample Solution Explorer window from a Web Application Project.

[5] You can download the Web Application Projects installation from http://msdn.microsoft.com/asp.net/reference/infrastructure/wap/default.aspx. Note that this project model does not install with the Express versions of the product.

Web Application Projects' Solution Explorer window


Unlike Web projects in Visual Studio .NET 2003, Web Application Projects do not require a virtual directory to be set up properly before the project can be opened. By default, they use the same ASP.NET Development Server listening on an open port for hosting pages, just as the Web site model does. They of course support the ability to work directly against a virtual directory hosted in IIS just as you can with Web sites.

The new partial class codebehind model is used by default with this model just like the Web site model does; however, it also supports the 1.1 style of codebehind with no issues, which means that migrating a site from Visual Studio .NET 2003 to Visual Studio 2005 is trivial using the Web Application Projects model. This makes it very appealing for larger sites that need to migrate to 2.0 without reworking all of their project settings and codebehind files. When the partial codebehind class model is used, there is a new source code file that is added called "xxx.aspx.designer.cs," where xxx is the name of the Web form. This file contains the control declarations that are added implicitly by ASP.NET in the Web site model. Many developers find this approach more compelling because all of the code for your codebehind classes is in one place and easy to view. It is no longer necessary to use the App_Code directory, because all source code files are compiled as part of the project (if they are included).

The following are some other advantages to using the Web Application Projects model:

  • Faster compile times. Since only the source code for the project is compiled when a build is performed, build times are fastersometimes much faster. The drawback is that syntax errors on .as*x files will not be detected until runtime.

  • All code files are compiled into a single assembly deployed in the local /bin directory, so it is easy to understand the dependencies in your project.

  • The project file lets you easily exclude files (and directories) from the build process, whereas in the Web site model you must rename a file with the .exclude extension to exclude it.

  • It uses the standard MSBuild compilation process, which can be extended using the MSBuild extensibility rules.

  • All debugging features available for projects are available, including features like Edit and Continue and pre- and post-processing steps.

Which model you end up using for building ASP.NET 2.0 applications depends on what environment you are working in and what you are used to. Web Application Projects were introduced to give enterprise developers used to working with project files and performing builds a way to incorporate their Web applications into their standard working environments. Future releases of Visual Studio will include Web Application Projects as one of the built-in options for creating Web applications with ASP.NET.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows