Compiling Conditional Code into ASP.NET Websites
In the software development lifecycle, there are three streams of environments; development, testing and production. For development environments you normally have extra information that is running to make the debugging experience easier, but for test and production environments you want that turned off so you can squeeze that extra bit of performance out of the application. Doing this can be a challenge without littering your source code with #if #else conditional compilation statements. Well this task is made simpler by the System.Diagnostics.ConditionalAttribute class. This class indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined. By using this class you can define builds for development environments so that debug or trace statements can be executed, and for production this can be removed from the assembly altogether.
To begin with open Visual Studio 2008 and choose File > New > Web > ASP.NET Web Application.
For this example, I want to demonstrate how to use conditional compilation statements to create different assemblies. I’ll create two builds; one for development and one for production. For development I want debugging information rendered in the browser, and for production I want that removed.
Getting started add a new class to the application and name it DebugOnly. As the name suggests this is for debug purposes only. Add the following code to the class:
public class DebugOnly
public void ShowDebugControls(System.Web.UI.WebControls.Label lbl)
lbl.Text = "Debug control displayed at: " + DateTime.Now.ToString();
lbl.Visible = true;
Public Class DebugOnly
Public Sub ShowDebugControls(ByVal lbl As System.Web.UI.WebControls.Label)
lbl.Text = "Debug control displayed at: " & DateTime.Now.ToString()
lbl.Visible = True
What makes the code special is that the method has been decorated with the Conditional attribute. The Conditional attribute accepts one parameter which is the string condition. This tells the compiler that this method should only be compiled if the conditional compilation symbol, DEVELOPMENT, is defined.
Jumping back to the Default.aspx page you’ll need to add a Label control to the page:
<asp:Label ID="lblDebug" runat="server" Visible="false" />
I will use this control to display some debugging information. Open the code behind file and add the following code:
protected void Page_Load(object sender, EventArgs e)
DebugOnly debug = new DebugOnly();
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim debug As New DebugOnly()
There is nothing special about the code above. An object reference is being created and the method is being called. But we only want this executed if this is a development build. To make this happen you need to right click the project in the Solution Explorer and select Properties:
The project properties window is open. Click on the Build tab and enter DEVELOPMENT in the conditional compilation symbols text box:
If you run the project you’ll see the Label is now visible and has bugging information that looks similar to this:
Debug control displayed at: 17/06/2009 11:40:17 PM
Moving on let’s assume we are happy with the code and are ready to deploy into production. Update the conditional compilation symbol from DEVELOPMENT to PRODUCTION. Run the project again.
See anything different? The label is not visible. How is this possible even though we have coded it to call the debug code in the page load event? Well the answer lies with the conditional compilation symbol. Because PRODUCTION was defined, the compiler has removed any code that references the methods decorated with [Conditional("DEVELOPMENT")].
To see what’s happening under the covers you’ll need to open ILDASM. ILDASM is an MSIL Disassembler tool that contains Microsoft intermediate language (MSIL) code. This is normally located in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin. Once it is opened, on the file menu select File > Open. Navigate to the current projects bin directory and add the projects assembly. ILDASM loads the two classes defined in the project; Default and DebugOnly:
If you expand _Default you will be able to see the Page_Load event. Double click this and a new window will open displaying the IL for the code:
The code that was calling the debug methods has been removed from the assembly. If we changed the build from PRODUCTION to DEVELOPMENT, the IL would look like this:
The code to call the debug method has been compiled back into the assembly. That’s pretty cool if you ask me!
By using conditional compilation symbols along with the System.Diagnostics.ConditionalAttribute class you can create different builds for different environments. And this is achieved without making you code unreadable and messy. Hopefully you can use this as much as I have in my projects.
The entire source code of this article can be downloaded over here