Sunday, December 16, 2007

UI: Good Use For Extension Methods

Ok, this is a little weird for me, but I think I just had my epiphany. I think I have finally converted in to an Extnsions Methods believer! I know, first there was C# 3.0 Extension Methods? A Good Idea? and then there was Reserving Judgement, but now I have found where I really, really like them.

How many of you have written a class like this:


public class Person
{
private string firstName;
private string lastName;

public string FirstName
{
get { return firstName; }
set { firstName = value; }
}

public string LastName
{
get { return lastName; }
set { lastName = value; }
}

public string GetFullName()
{
return LastName + ", " + FirstName;
}
}


I don't know about you, but I feel dirty every time I write something like that. To me this is display logic, and now it's polluting my business objects! This really smells to me. This smells so bad that I prefer to put a method on my page which does the formatting for me. But the problem is that people are used to this sort of syntax. They expect this to be how they format that class.

How do we satisfy both sides? Keep the presentation logic out of the business layer, yet keep the interfaces clean? Enter Extension Methods!

In order to solve this problem I would now create a new static class in my web assembly (UIHelper possibly, or another name that fits). This new class would look like the following:


public static class UIHelper
{
public static string GetFullName(this Person person)
{
return person.LastName + ", " + person.FirstName;
}
}


Now you can take the GetFullName method out of the Person class and use the extension method in your UI layer instead. The class will still work exactly the same way from a UI perspective, except when working within the Person there will no longer be a GetFullName method.

The Person class now looks like this:

public class Person
{
private string firstName;
private string lastName;

public string FirstName
{
get { return firstName; }
set { firstName = value; }
}

public string LastName
{
get { return lastName; }
set { lastName = value; }
}
}


Just make sure you add the using directive to the namespace which contains the UIHelper class on your page (or add an Import directive to your aspx file). Your code on the page now looks like the following:

This is actually the happiest I've been with any use of extension methods when you control the class which is being extended.

--John Chapman

3 comments:

Greg said...

John,

Too be honest I am not sure if I like this. The reason I am not sure on it is that the extension method is not carried to the instance and is therefore not easily usable with many data binding systems as they tend to use reflection in order to access the data.

That said I think I would like this with a slight alteration. If the extension method were to return a context sensitive presenter object then I think this could be very slick as it would help remove the 'code explosion' in the actual object as you added presenters to it.

Cheers,

Greg

John Chapman said...

Greg,

I think I had a bit of tunnel vision. I typically work with Web Applications where I don't believe your concern would be nearly as much of an issue. I don't use databinding for web applications after all.

This is probably not sufficient for winforms, or WPF (I actually have yet to really look at WPF).

Your points are noted though, maybe another approach would work well in those environments.

David said...

You have been imortalized above the Penis Operator!

http://geekswithblogs.net/davenet/archive/2007/12/18/117801.aspx

Blogger Syntax Highliter