Ang3lFir3 – Life as a Code Poet

July 28, 2008

Specification Pattern and Lambdas

While working on my current project I decided that I had a need to use the Specification Pattern . After finding a clean implementation by Jeff Perrin I set to work creating the specifications that I needed. I quickly realized that we were going to end up having a ton of specifications and sometimes they would only apply to very special cases. Other times they would be very broad cases and they needed to be even more composable than even the fluid interface implemented in Jeff’s implementation wasn’t going to be enough. It after all still required me to create a concrete implementation for each specification, no matter how minuscule it might be.

This is the part where I thought to my self that since i was really only creating implementations for a single method that I could just write a LambdaSpecification and be able to use this for all the special cases I had.

Below is the LambdaSpecification Code:


using System;
using System.Linq.Expressions;

namespace Specification
{
    public class LambdaSpecification<T> : Specification<T>
    {
        private Func<T,bool> _expression;

        public LambdaSpecification(Func<T,bool> expression)
        {
             if(expression ==null) throw new ArgumentNullException(“expression”);
              _expression = expression;
        }

        public override bool IsSatisfiedBy(T obj)
        {
            return _expression(obj);
        }
    }
}

And the Tests:


[Test]
public void LambdaSpecification_CanExecuteSimpleLambda()
{
    var p = new Person() {Name = "Eric"};
    var spec = new LambdaSpecification<Person>(x => x.Name == "Eric");

        Assert.IsTrue(spec.IsSatisfiedBy(p));
}

[Test]
public void LambdaSpecification_CanExecuteComplexLambda()
{
    var p = new Person() {Name = “Eric”, Age = 28};
    var spec = new LambdaSpecification<Person>(x => x.Name == “Eric” &&
                                                                        new IsLegalDrinkingAgeSpecification().IsSatisfiedBy(x));

    Assert.IsTrue(spec.IsSatisfiedBy(p));
}

//Might Not be needed but I wanted to be sure
[Test]
public void LambdaSpecification_CanExecuteLambda_AndUseAndSpecification()
{
    var p = new Person() {Name = “Eric”, Age = 28};
    var spec = new LambdaSpecification<Person>(x => x.Name == “Eric” );

    Assert.IsTrue(spec.And(new IsLegalDrinkingAgeSpecification()).IsSatisfiedBy(p));
}

Comments are welcome and encouraged, especially if you see a reason why I shouldn’t be doing this. Or, if you have any ways to make this better, I would love to hear them. This is the first time I have ever used a lambda as a parameter in my own code and so far i am liking it.

Thanks to Jeff Perrin again for his post on creating a clean implementation of the specification pattern.

**EDIT: Thanks to Greg Beech for his input. I’ve updated the code to reflect his suggestions.

kick it on DotNetKicks.com

About these ads

9 Comments »

  1. Hi ,
    C# is gonna be a prominent language. Lambda Expression is one of the best features added , especially when pit into work in LINQ.
    Have nice time working with C# ,

    Comment by Alireza — July 28, 2008 @ 10:22 pm

  2. [...] bookmarks tagged special Specification Pattern and Lambdas saved by 1 others     mateohol1 bookmarked on 07/29/08 | [...]

    Pingback by Pages tagged "special" — July 28, 2008 @ 10:43 pm

  3. Seems a decent way to do it; I’ve done similar things in the past to create a dynamic IComparer implementations. Couple of slight changes you might want to make though:

    1. There’s no need to take an Expression[Func[T,bool]] type, as this just means more work at runtime to compile it – instead you can just take a Func[T,bool] which will be compiled at compile-time.

    2. You don’t need to write _expression.Invoke(obj) – you can simply write _expression(obj) because it is a method in itself.

    Also – you allow null in the constructor so should probably check for this in the IsSatisfiedBy method, because at the moment you could pass null to the constructor then get a NullReferenceException in that method.

    Comment by Greg Beech — July 29, 2008 @ 5:17 am

  4. Why not make it a Predicate?

    Comment by Mark — July 29, 2008 @ 6:37 am

  5. @Greg — Thanks for the imput. I understand what you mean now and will be implementing your changes. As to null… I have since rewritten that bit in the constructor… I seem to always forget about that kind of thing. THANKS!!

    Comment by ang3lfir3 — July 29, 2008 @ 7:31 am

  6. @Mark: Func is functionally equivalent to Predicate, but Predicate (and the other .NET 2.0 delegate definitions) have been “unofficially deprecated” in .NET 3.5. I base this on the fact that LINQ uses Func exclusively.

    Comment by Nate Kohari — July 29, 2008 @ 7:49 am

  7. @Greg and @ang3lfir3, Expression[Func[T, bool]] is required (rather than just Func[T, bool]) if you want to use the specifications with a Linq-based data access framework.

    If you use Func only, you’re restricted to being able to test against only objects that are already in memory, which is inefficient when large numbers of objects are involved.

    I took a shot at exactly that here: http://ubik.com.au/article/named/implementing_the_specification_pattern_with_linq – hopefully the article might shed some light on how specs using Linq can be used for the dual purposes of in-memory and database object selection.

    Cheers!
    Nick

    Comment by Nicholas Blumhardt — September 9, 2008 @ 5:00 pm

  8. omg junior?! is that you?!

    .drc

    Comment by ruadh — September 26, 2008 @ 5:35 am

    • Nice blog entry but I’m not really sure if this is correct use of specification pattern here. Why not use a straight conditional or method that would return a bool for more complex logic. Specification pattern should be used for explicit description of more complex logic that can be reused in other classes as I understand.

      Comment by benek — January 12, 2010 @ 5:04 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: