Web Development & Execution
David Addison
by David Addison
share this
?fl
« Back to the Blog

Extending ASP.NET Using C# extension methods

01/19/2011
Extending ASP.NET Using C# extension methods

This article explains in depth how to minimize the use of a static utilities class by using extension methods. Extension methods allow you to literally extend the implementation of standard ASP.NET types (classes, server controls, etc). If you are like me you will want to skip to the good stuff (code).

As an application developer and computer science afficianado I am always concerned with the pattern of implentation. For instance, how useable or extendable is the code that you write? Good code should, of course, be optmized as well as highly portable and adaptable. But one of the most important aspects is how intuitive is the pattern or implementation. Let's take a step back and look at your code library implementations. The parts that we are concerned with are naming convention and object hierarchy. Does this name properly identify this object, is it in the right namespace, etc.?

For the most part code libraries tend to follow a similar hierarchy and naming convention. Most likely your code library has these namespaces:

  • ProjectName.Web.UI
  • ProjectName.Web.UI.Controls
  • ProjectName.Data
  • Etc...

These namespaces follow a similar pattern to ASP.NET which is great because we don't want to have to remember different structures for every assembly. Likewise we want to try to minimize the caveats that inherently arise in the heat of development to keep our assemblies as homogeneous as possible. Oftentimes to solve a problem it is recommended that you implement a static Utilities class to stuff methods that do not necessarily fit anywhere else in your hierarchy. This is a commonly accepted practice, however I have seen Utility classes with thousands of lines of code; many of these methods are also responsible for different things. In my opinion, this is poor pattern design.

An example of an out of control Utilities class would be a class that makes database connections, sends e-mail, modifies web controls, and so forth. The database connections should be in a Data namespace and e-mail should be in an Email namespace. Onto extending built in controls!

I will now set up our thought experiment lab scenario. You have a website. This website has an image-based top navigation. To perform your image rollovers you have three variations of one image. There is an off state, a hover state, and an "active" state when the user is currently browsing the page or section that that user is in. When the page loads there is Javascript code that parses the DOM for images containing "_off" and sets up their onmouseover and onmouseout events to replace "_off" with "_over". This is a form of automatic rollover that does not require hand coding to make the rollover happen. This is the boiled down Javascript code that would trigger on mouseover:

var tmpImage = new Image(); tmpImage.src = imgs[i].src.replace('_off', '_over');

We literally replace "_off" with "_over" in the src attribute of the image. Then we want to display the "_active" image for the tab in the navigation that the user is currently on. We do this in ASP.NET to accomodate users that have Javascript turned off. If they have Javascript turned off they will not have rollovers but at least they will have an "_active" image. Assuming that we are using asp:Image objects on our aspx page, here are a few ways that we could code this:

 

 

Hard Code it:

ImgButton1.ImageUrl = "/images/path_to_file/ImgButton1_active.jpg";

Replace technique:

ImgButton1.ImageUrl = ImgButton1.ImageUrl.Replace("_off", "_active");

Utilities method:

public static class Utilities
{
public static void ImgMakeActive(ref Image img)
{
img.ImageUrl = img.ImageUrl.Replace("_off", "_over");
}
}

......

Utilities.ImgMakeActive(ref ImgButton1);

These are all acceptable solutions, however using extension methods will allow us to cut through lots of syntactic fluff. Here is what the syntax looks like using extension methods:

ImgButton1.MakeActive();

Pretty simple right? Also very cool because we have added a new method named "MakeActive()" to the standard System.Web.UI.Webcontrols.Image class. Ok, let's look at how we implement this. First you will want to create a new namespace. This namespace will have to be included wherever you want to use your extension methods. So let's assume that this namespace is ProjectName.Extensions. Next make a new class file for your "MakeActive" method. The class name should be "MyExtensions" or whatever you want to call it. Here is what the implementation of an extension method looks like:

using System.Web.UI.WebControls;

namespace ProjectName.Extensions
{
public static partial class MyExtensions
{
public static void MakeActive(this Image img)
{
img.ImageUrl = img.ImageUrl.Replace("_off", "_active");
}
}
}

You can see that we have more or less the same code replacing "_off" with "_active"; however this puts the code in a single, central place. This is important because if we ever have to update it, we only have to go to one place. Include ProjectName.Extensions and all of your System.Web.UI.Webcontrols.Image classes will have the method "MakeActive()". You can see that the method itself takes an argument of "this Image img" with 'this' being the keyword, which turns this almost regular method into an extension method that extends the Image class.

Also it would be good to note that I have used a public static partial class. By making this class partial we are able to define this across different files in the same assembly, instead of piling all your code into one file called MyExtensions.cs you can now break it up into method files (e.g. one called MakeActive.cs and other files that define methods that belong to the class "MyExtensions").

Thanks!

Thank you for contacting us!

We'll be in touch!

Back Home ×