Showing posts with label Extension methods. Show all posts
Showing posts with label Extension methods. Show all posts

Friday, July 18, 2008

Extension Method + LINQ + Interface = Reusable Queries

One of the requirements of Suteki Shop is that admin users should be able to create various new entities (categories, products, content etc) before they are published on the public web site. To this end I created a simple interface, IActivatable:

public interface IActivatable
{
   bool IsActive { get; set; }
}

As you can see it's got a single property 'IsActive'. Any entity that needs to be active/inactive implements it. So my product class' partial class definition looks like this:

public partial class Product : IOrderable, IActivatable, IUrlNamed
{
 ....
}

I'll explain IOrderable and IUrlNamed later, but they do similar things. Each entity has a matching table in the database and each entity that implements IActivatable also has a bit column IsActive. Here are Category and Product:

Product_Category_DB

When I drag these tables onto the LINQ-to-SQL design surface, Product and Category classes are created with IsActive properties. I can make their matching partial classes implement IActivatable and the designer IsActive property satisfies the implementation requirement.

Now I can write a reusable LINQ query extension method for any IActivatable to filter only active items:

public static IQueryable<T> Active<T>(this IQueryable<T> items) where T : IActivatable
{
   return items.Where(item => item.IsActive);
}

Now every time I need a list of active items I can just chain the query with Active(),

var products = productRepository.GetAll().Active();

Remember the IOrderable and IUrlNamed interfaces that the Product partial class implemented? They work in exactly the same way. I explained IOrderable in a previous post, it's used to create a generic service to order and re-order lists of entities. IUrlNamed provides a generic way of querying entities given a unique string from the URL. For example, Suteki Shop has nice URLs for products: http://sutekishop.co.uk/product/East_End_Trilby. So there's an extension method:

public static T WithUrlName<T>(this IQueryable<T> items, string urlName) where T : IUrlNamed
{
   T item = items
       .SingleOrDefault(i => i.UrlName.ToLower() == urlName.ToLower());

   if (item == null) throw new ApplicationException("Unknown UrlName '{0}'".With(urlName));
   return item;
}

That allows us to look up products like this:

public ActionResult Item(string urlName)
{
   Product product = productRepository.GetAll().WithUrlName(urlName);
   return View("Item", ShopView.Data.WithProduct(product));
}

Saturday, May 31, 2008

Interface + Extension Methods = Mixin

Mixins are a language idea similar to multiple inheritance, but rather than extending a class a mixin works by defining an interface plus various functionality associated with that interface. It avoids the pathologies of multiple inheritance and is a flexible way of providing add-on functionality.

In C# we can create a mixin with a combination of an interface plus extension methods. LINQ is the canonical example of this with two core interfaces IEnumerable<T> and IQueriable<T> and a collection of extension methods on those interfaces.

It's easy to create your own mixins. For example, say I want to provide location functionality to various entities. I can define an interface like this:

public interface ILocatable
{
   int Longitude { get; set; }
   int Latitude { get; set; }
}

And then some extension methods for that interface:

public static class LocatableExtensions
{
   public static void MoveNorth(this ILocatable locatable, int degrees)
   {
       // ...
   }

   public static void MoveWest(this ILocatable locatable, int degrees)
   {
       // ..
   }
}

Now, if we've got some entities like:

public class Ship : ILocatable
{
   public int Longitude { get; set; }
   public int Latitude { get; set; }
}

public class Car : ILocatable
{
   public int Longitude { get; set; }
   public int Latitude { get; set; }
}

We can use the mixin like this:

Ship ship = new Ship(); ship.MoveNorth(10); Car car = new Car(); car.MoveWest(23);

It's a very nice pattern for adding capabilities to entities.

Monday, February 11, 2008

Extension method validators

I'm building an MVC Framework application at the moment and I wanted a simple, easy to grep way of validating fields passed back from forms. In MVC-land all the form variables are passed as parameters to the action method. Extension methods turned out to be a very neat solution for doing validation and data conversion. Here's an example:

[ControllerAction]
public void UpdateContact(
    int contactId,
    string name,
    string address1,
    string address2,
    string address3,
    string county,
    string postcode,
    string telephone,
    string email)
{
    try
    {
        name.Label("Name").IsRequired();
        address1.Label("Address 1").IsRequired();
        county.Label("County").IsRequired();
        postcode.Label("Postcode").IsRequired().IsPostcode();
        telephone.Label("Telephone").IsRequired().IsTelephoneNumber();
        email.Label("Email").IsRequired().IsEmail();
    }
    catch (ValidationException exception)
    {
        ContactViewData viewData = ContactViewData(contactId);
        viewData.ErrorMessage = exception.Message;
        RenderView("Contact", viewData);
        return;
    }

 // update the contact and render the view
}

As you can see we pass the contact's details from a form. In the try block the extension method validators are called. Any of them can raise a validation exception which is caught by the catch block and a view is rendered showing the validation error.

The 'Label' extension returns a ValidateField instance that can be consumed by any other validator, this is so that we can raise exceptions that can be displayed directly to the user:

public static ValidateField Label(this string value, string label)
{
    return new ValidateField { Value = value, Label = label };
}

The 'IsRequired' extension takes a ValidateField and checks that the value is not null or empty:

public static ValidateField IsRequired(this ValidateField validateField)
{
    if (string.IsNullOrEmpty(validateField.Value))
    {
        throw new ValidationException(string.Format("{0} is required", validateField.Label));
    }
    return validateField;
}

And finally the 'IsEmail' extension uses a Regex to validate the string value:

public static ValidateField IsEmail(this ValidateField validateField)
{
    // ignore is null or empty, use IsRequired in parrallel to check this if needed
    if (string.IsNullOrEmpty(validateField.Value)) return validateField;

    string patternLenient = @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
    if (!Regex.Match(validateField.Value, patternLenient).Success)
    {
        throw new ValidationException(string.Format("{0} must be a valid email address", validateField.Label));
    }
    return validateField;
}

I'm finding extension methods a real boon for writing DSL-ish APIs. I'll leave the 'IsTelephone' and 'IsPostcode' exercises for your enjoyment :)

Sunday, February 03, 2008

Never write a for loop again! Fun with Linq style extension methods.

One of the things I like about Ruby is the range operator. In most C style languages in order to create a list of  numbers you would usually use a for loop like this:

List<int> numbers = new List<int>();
for (int i = 0; i < 10; i++)
{
    numbers.Add(i);
}
int[] myArray = numbers.ToArray();

But in Ruby you just write this:

myArray = o..9.to_a

But now with extension methods and custom iterators we can do the same thing in C#. Here's a little extension method 'To':

public static IEnumerable<int> To(this int initialValue, int maxValue)
{
    for (int i = initialValue; i <= maxValue; i++)
    {
        yield return i;
    }
}

You can use it like this:

1.To(10).WriteAll();

1 2 3 4 5 6 7 8 9 10

Note the WriteAll() method, that's an extension method too, it simply writes each item in the list to the console:

public static void WriteAll<T>(this IEnumerable<T> values)
{
    foreach (T value in values)
    {
        Console.Write("{0} ", value);
    }
    Console.WriteLine();
}

You can mix your custom extension methods with the built in Linq methods, let's count up to fifty in steps of ten:

1.To(5).Select(i => i * 10).WriteAll();

10 20 30 40 50

Or maybe just output some even numbers:

1.To(20).Where(i => i % 2 == 0).WriteAll();

2 4 6 8 10 12 14 16 18 20

Here's another extension method 'Each', it just applies a Lambda expression to each value:

public delegate void Func<T>(T value);

public static void Each<T>(this IEnumerable<T> values, Func<T> function)
{
    foreach (T value in values)
    {
        function(value);
    }
}

Let's use it to output a ten by ten square of zero to ninety nine:

0.To(9).Each(i => 0.To(9).Select(j => (i * 10) + j).WriteAll());

0 1 2 3 4 5 6 7 8 9 
10 11 12 13 14 15 16 17 18 19 
20 21 22 23 24 25 26 27 28 29 
30 31 32 33 34 35 36 37 38 39 
40 41 42 43 44 45 46 47 48 49 
50 51 52 53 54 55 56 57 58 59 
60 61 62 63 64 65 66 67 68 69 
70 71 72 73 74 75 76 77 78 79 
80 81 82 83 84 85 86 87 88 89 
90 91 92 93 94 95 96 97 98 99 

Now here's something really cool, and more than a little dangerous. Because chaining extension methods of IEnumerable<T> means that you're effectively building a decorator chain of enumerators, you don't actually execute every iteration unless you ask for it. This means we can write infinite loop generators and then bound them by only asking for some members. Best to demonstrate. Here's a method that returns an infinite number of integers (not really, it'll end with an exception at int.MaxValue):

public static IEnumerable<int> Integers
{
    get
    {
        int i = 0;
        while (true)
        {
            yield return i++;
        }
    }
}

We can use it with the built in Linq method 'Take'. For example here we are printing out zero to nine:

Numbers.Integers.Take(10).WriteAll();

0 1 2 3 4 5 6 7 8 9

And here is Five to Fifteen:

Numbers.Integers.Skip(5).Take(11).WriteAll();

5 6 7 8 9 10 11 12 13 14 15

Why is it dangerous? If you put any operation in the chain that simply iterates all the values you'll get an infinite loop. So you couldn't say:

Numbers.Integers.Reverse.Take(10).WriteAll();

Let's wrap up with an infinite Fibonacci series:

public static IEnumerable<int> Fibonacci
{
    get
    {
        int a = 0;
        int b = 1;
        int t = 0;

        yield return a;
        yield return b;

        while (true)
        {
            yield return t = a + b;
            a = b;
            b = t;
        }
    }
}

And use it to print out the first ten Fibonacci numbers:

Numbers.Fibonacci.Take(10).WriteAll();

0 1 1 2 3 5 8 13 21 34

I'm really enjoying learning the possibilities of Linq style extension methods. It makes C# feel much more like a functional language and let's you write in a nicer declarative style. If I've tickled your interest, check out Wes Dyer's blog. Here he writes an ASCII art program using Linq. Nice!