Specification pattern: C# implementation

By Vladimir Khorikov

Specification pattern is not a new topic, there are many of its implementations on the Internet already. In this post, I’d like to discuss the use cases for the pattern and compare several common implementations to each other.

Specification pattern: what’s that?

Specification pattern is a pattern that allows us to encapsulate some piece of domain knowledge into a single unit – specification – and reuse it in different parts of the code base.

Use cases for this pattern are best expressed with an example. Let’s say we have the following class in our domain model:

public class Movie : Entity

{

    public string Name { get; }

    public DateTime ReleaseDate { get; }

    public MpaaRating MpaaRating { get; }

    public string Genre { get; }

    public double Rating { get; }

}

 

public enum MpaaRating

{

    G,

    PG13,

    R

}

Now, let’s assume that users want to find some relatively new movies to watch. To implement this, we can add a method to a repository class, like this:

public class MovieRepository

{

    public IReadOnlyList<Movie> GetByReleaseDate(DateTime minReleaseDate)

    {

        /* … */

    }

}

If we need to search by rating or genre, we can introduce other methods as well:

public class MovieRepository

{

    public IReadOnlyList<Movie> GetByReleaseDate(DateTime maxReleaseDate) { }

 

    public IReadOnlyList<Movie> GetByRating(double minRating) { }

 

    public IReadOnlyList<Movie> GetByGenre(string genre) { }

}

Things get a bit more complicated when we decide to combine the search criteria, but we are still in a good shape. We can introduce a single Find method which would handle all possible criteria and return a consolidated search result:

public class MovieRepository

{

    public IReadOnlyList<Movie> Find(

        DateTime? maxReleaseDate = null,

        double minRating = 0,

        string genre = null)

    {

        /* … */

    }

}

And of course, we can always add other criteria to the method as well.

Problems arise when we need to not only search for the data in the database but also validate it in the memory. For example, we might want to check that a certain movie is eligible for children before we sell a ticket to it, so we introduce a validation, like this:

public Result BuyChildTicket(int movieId)

{

    Movie movie = _repository.GetById(movieId);

 

    if (movie.MpaaRating != MpaaRating.G)

        return Error(“The movie is not eligible for children”);

 

    return Ok();

}

If we also need to look into the database for all movies that meet the same criterion, we have to introduce a method similar to the following:

public class MovieRepository

{

    public IReadOnlyList<Movie> FindMoviesForChildren()

    {

        return db

            .Where(x => x.MpaaRating == MpaaRating.G)

            .ToList();

    }

}

The issue with this code is that it violates the DRY principle as the domain knowledge about what to consider a kids movie is now spread across 2 locations: the BuyChildTicket method and MovieRepository. That is where the Specification pattern can help us. We can introduce a new class which knows exactly how to distinguish different kinds of movies. We then can reuse this class in both scenarios:

public Result BuyChildTicket(int movieId)

{

    Movie movie = _repository.GetById(movieId);

 

    var spec = new MovieForKidsSpecification();

 

    if (!spec.IsSatisfiedBy(movie))

        return Error(“The movie is not eligible for children”);

 

    return Ok();

}

public class MovieRepository

{

    public IReadOnlyList<Movie> Find(Specification<Movie> specification)

    {

        /* … */

    }

}

Not only does this approach removes domain knowledge duplication, it also allows for combining multiple specifications. That, in turn, helps us easily set up quite complex search and validation criteria.

There are 3 main use cases for the Specification pattern:

  • Looking up data in the database. That is finding records that match the specification we have in hand.
  • Validating objects in the memory. In other words, checking that an object we retrieved or created fits the spec.
  • Creating a new instance that matches the criteria. This is useful in scenarios where you don’t care about the actual content of the instances, but still need it to have certain attributes.

We will discuss the first 2 use cases as they are the most common in my experience.

Naive implementation

We’ll start implementing the specification pattern with a naive version first and will then move forward to a better one.

The first solution that comes to mind when you face the problem described above is to use C# expressions. To a great extent, they themselves are an implementation of the specification pattern. We can easily define one in code and use it in both scenarios, like this:

// Controller

public void SomeMethod()

{

    Expression<Func<Movie, bool>> expression = m => m.MpaaRating == MpaaRating.G;

    bool isOk = expression.Compile().Invoke(movie); // Exercising a single movie

    var movies = _repository.Find(expression); // Getting a list of movies

}

 

// Repository

public IReadOnlyList<Movie> Find(Expression<Func<Movie, bool>> expression)

{

    return db

        .Where(expression)

        .ToList();

}

The problem with this approach, however, is that while we do gather the domain knowledge regarding how to categorize kids movies in a single place (expression variable in our case), the abstraction we’ve chosen isn’t a good fit. Variables are by no means a suitable place for such important information. The domain knowledge represented in such a way is hard to reuse and tends to be duplicated across the whole application because of that. Ultimately, we end up with the same issue we started off with.

A variation of this naive implementation is introducing a generic specification class:

public class GenericSpecification<T>

{

    public Expression<Func<T, bool>> Expression { get; }

 

    public GenericSpecification(Expression<Func<T, bool>> expression)

    {

        Expression = expression;

    }

 

    public bool IsSatisfiedBy(T entity)

    {

        return Expression.Compile().Invoke(entity);

    }

}

// Controller

public void SomeMethod()

{

    var specification = new GenericSpecification<Movie>(

        m => m.MpaaRating == MpaaRating.G);

    bool isOk = specification.IsSatisfiedBy(movie); // Exercising a single movie

    var movies = _repository.Find(specification); // Getting a list of movies

}

// Repository

public IReadOnlyList<Movie> Find(GenericSpecification<Movie> specification)

{

    return db

        .Where(specification.Expression)

        .ToList();

}

This version has essentially the same drawbacks, the only difference is that here we have a wrapper class on top of the expression. Still, in order to reuse such specification properly, we have to create a single instance of it once and then share this instance across our code base somehow. This design doesn’t help much with DRY.

That leads us to an important conclusion: generic specifications are a bad practice. If a specification allows you to indicate an arbitrary condition, it becomes just a container for the information which is passed to it by its client and doesn’t solve the underlying problem of domain knowledge encapsulation. Such specifications simply don’t contain any knowledge themselves.

Strongly-typed specifications

So how can we overcome the problem? The solution here is to use strongly-typed specifications. That is specifications in which we hard code the domain knowledge, with little or no possibility to alter it from the outside.

Here’s how we can implement it in practice:

public abstract class Specification<T>

{

    public abstract Expression<Func<T, bool>> ToExpression();

 

    public bool IsSatisfiedBy(T entity)

    {

        Func<T, bool> predicate = ToExpression().Compile();

        return predicate(entity);

    }

}

public class MpaaRatingAtMostSpecification : Specification<Movie>

{

    private readonly MpaaRating _rating;

 

    public MpaaRatingAtMostSpecification(MpaaRating rating)

    {

        _rating = rating;

    }

 

    public override Expression<Func<Movie, bool>> ToExpression()

    {

        return movie => movie.MpaaRating <= _rating;

    }

}

// Controller

public void SomeMethod()

{

    var gRating = new MpaaRatingAtMostSpecification(MpaaRating.G);

    bool isOk = gRating.IsSatisfiedBy(movie); // Exercising a single movie

    IReadOnlyList<Movie> movies = repository.Find(gRating); // Getting a list of movies

}

// Repository

public IReadOnlyList<T> Find(Specification<T> specification)

{

    using (ISession session = SessionFactory.OpenSession())

    {

        return session.Query<T>()

            .Where(specification.ToExpression())

            .ToList();

    }

}

With this approach, we lift the domain knowledge to the class level making it much easier to reuse. No need to keep track of spec instances anymore: creating additional specification objects doesn’t lead to the domain knowledge duplication, so we can do it freely.

Also, it’s really easy to combine the specifications using And, Or, and Not methods. Here’s how we can do that:

public abstract class Specification<T>

{

    public Specification<T> And(Specification<T> specification)

    {

        return new AndSpecification<T>(this, specification);

    }

 

    // And also Or and Not methods

}

public class AndSpecification<T> : Specification<T>

{

    private readonly Specification<T> _left;

    private readonly Specification<T> _right;

 

    public AndSpecification(Specification<T> left, Specification<T> right)

    {

        _right = right;

        _left = left;

    }

 

    public override Expression<Func<T, bool>> ToExpression()

    {

        Expression<Func<T, bool>> leftExpression = _left.ToExpression();

        Expression<Func<T, bool>> rightExpression = _right.ToExpression();

 

        BinaryExpression andExpression = Expression.AndAlso(

            leftExpression.Body, rightExpression.Body);

 

        return Expression.Lambda<Func<T, bool>>(

            andExpression, leftExpression.Parameters.Single());

    }

}

And this is a usage example:

var gRating = new MpaaRatingAtMostSpecification(MpaaRating.G);

var goodMovie = new GoodMovieSpecification();

var repository = new MovieRepository();

 

IReadOnlyList<Movie> movies = repository.Find(gRating.And(goodMovie));

You can find the full source code and usage examples on Github.

Returning IQueryable<T> from a repository

A question that is somewhat related to the specification pattern is: can repositories just return an IQueryable<T>? Wouldn’t it be easier to allow clients to query data from the backing store the way they want? For example, we could add a method to the repository like this:

// Repository

public IQueryable<T> Find()

{

    return session.Query<T>();

}

And then use it in a controller specifying the actual criteria ad hoc:

// Controller

public void SomeMethod()

{

    List<Movie> movies = _repository.Find()

        .Where(movie => movie.MpaaRating == MpaaRating.G)

        .ToList();

}

This approach has essentially the same drawback as our initial specification pattern implementation: it encourages us to violate the DRY principle by duplicating the domain knowledge. This technique doesn’t offer us anything in terms of consolidating it in a single place.

The second drawback here is that we are getting database notions leaking out of repositories. The implementation of IQueryable<T> highly depends on what LINQ provider is used behind the scene, so the client code should be aware that there potentially are queries which can’t be compiled into SQL.

And finally, we are also getting a potential LSP violation. IQueryables are evaluated lazily, so we need to keep the underlying connection opened during the whole business transaction. Otherwise, the method will blow up with an exception. By the way, an implementation with IEnumerables have essentially the same problem, so the best way to overcome this issue is to return IReadOnlyList or IReadOnlyCollection interfaces.

Source code

Full source code for the specification pattern implementation in C#

Summary

  • Don’t use C# expressions as a Specification pattern implementation, they don’t allow you to actually gather the domain knowledge into a single authoritative source.
  • Don’t return IQueryable<T> from repositories, it brings up issues with DRY and LSP violation and leaking database concerns to the application logic.




  • Miguel Bruno Gouveia

    Very good post.
    You just have a minor typo in your code.

    In function “IsSutisfiedBy” I think it should be “IsSatisfiedBy”.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Ah, indeed! Fixed that, thanks!

  • Crash Collison

    Why did you use Expressions instead of unwrapped Funcs?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Expressions are required for the use with ORMs (such as NHibernate and Entity Framework).

  • Dimitris Foukas

    Thanks for sharing the code for the spec pattern. I have two issues on your closing remarks about IQueryable – quotes are from your article:

    1- “The second drawback here is that we are getting database notions leaking out of repositories. The implementation of IQueryable highly depends on what LINQ provider is used behind the scene, so the client code should be aware that there potentially are queries which can’t be compiled into SQL”

    I think this drawback is simply the accidental complexity paid by the inability of today’s LINQ providers (and also of the hosting language type system limitations) to protect client from using functions not supported by the underlying data source. As an alternative consider that F# Data provider http://fsprojects.github.io/FSharp.Data.SqlClient/ provides compile time protection to the above stated problem – albeit for SQL Server only.

    2- “And finally, we are also getting a potential LSP violation. IQueryables are evaluated lazily, so we need to keep the underlying connection opened during the whole business transaction. Otherwise, the method will blow up with an exception. By the way, an implementation with IEnumerables have essentially the same problem, so the best way to overcome this issue is to return IReadOnlyList or IReadOnlyCollection interfaces”

    I agree is that in the post .Net 4.5 world IReadOnly interfaces should be favoured instead of streaming IEnumerable interfaces for in-memory collections in Entities even for (connected) Web App scenarios. IMO IQueryables add a different “dimension” to the problem – lazy evaluation here is what allows query composition. In a project I am currently working on I have the requirement that the application layer should be able to define ad-hoc queries and, in addition, we don’t want to pay the price of serializing the entire object graph to the client (its a SPA). You see, the majority of use cases involves only a handful of attributes from each entity involved. I understand that the onion architecture prescribes that Repositories should be expressed using the Domain entities and not DTOs that are defined in some layer above, nevertheless don;t you think that it is a pragmatic compromise to “encode Repository queries” in a way that layers above can add their concerns? IMO, this practically mean using IQs in the signature of Find methods. You dont need to perform them After all queries are not done in a UoW, right?

    I have to admit – I am not versed in DDD therefore what I am proposing does not make much sense …

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thanks for your comment. Your concerns make a lot of sense.

      I think this drawback is simply the accidental complexity paid by the inability of today’s LINQ providers to protect client from using functions not supported by the underlying data source.

      Absolutely. That’s essentially a variation of the issue with LSP: the IQueriable interface promises things it can’t fulfil. Replacing the general IQueriable Find() method with a specific IReadOnlyList Find(Spec spec) one, we narrow the promises the method gives down to a very specific set of specifications our Repository can handle.

      IMO IQueryables add a different “dimension” to the problem – lazy evaluation here is what allows query composition

      I didn’t state it in the article, but specifications actually do allow for the query composition as well, and I implemented it in the sample project: https://github.com/vkhorikov/SpecificationPattern/blob/master/SpecificationPattern.Tests/Tests.cs#L68

      Ultimately, I don’t see any benefits in using IQs for the sake of composability as specs allow us to implement the same functionality without the accompanying drawbacks.

      However, I do understand your sentiments regarding the simplicity of the model with a single generic IQueriable Find() method. I would say that if the problem domain isn’t too complex, there’s indeed not much sense in a proper Specification pattern implementation, the approach you propose would work just fine. After all, we should be pragmatic and follow the KISS principle at all times.

      • Dimitris Foukas

        To recap the discussion so far:
        IQ exposes db concerns outside the repository therefore if we REALLY require fluent queries its better to implement our own Specification DSL that takes into account the constraints of our domain. Fine, can you also comment on the return types of Repository methods: should they be (collections of) Domain entities or should be pragmatically leaning towards DTOs – non withstanding the issues that we have with “stability” of our repositories when new Use Cases arise…

        I noticed that elsewhere in your blog http://enterprisecraftsmanship.com/2015/04/20/types-of-cqrs/ you allude to the possibility that a scalable DDD implementation should only use a “proper” ORMs for the write portion of the domain logic whereas the read portion could be implemented with a a micro-ORM. I know I am asking a lot but it would be helpful if you could provide a Github demonstration of this approach which I think is very pragmatic – especially Type 2 in your taxonomy!

        May I also suggest that this topic constitutes a candidate for a follow-up to your excellent PS DDD course!

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Ideally, if we follow the Onion Architecture principle, repositories should return domain entities or raw data only. Application services then can use them to produce DTOs. I, however, usually tend to take a shortcut here and make repositories return DTOs directly.

          Sorry, I don’t have a fully-fledged example of Type 2 of CQRS. But essentially it is about extracting all methods returning DTOs from repositories to a separate read model. So that, if the Application Services layer doesn’t need to change anything, it can go to the that read model and ask for the required information directly, without appealing to the domain model.

          I think this might indeed become a good topic for a future PS course, thanks for the suggestion!

  • http://www.dox.com.au/ Ian Yates

    Agree with not returning IQueryable, but if someone was to do so they shouldn’t copy the code that’s here 🙂 The using statement wrapping the return of the IQueryable means the created database connection/session is disposed before the caller gets their hands on the IQueryable

  • Alexander Yevseyev

    Vladimir, thank you for an excellent article. It combines best practices I met earlier. But I think you should have added the examples of specification composition: And, Or, Not. Also because you’ve mentioned them in comments and actually made in your sample project: https://github.com/vkhorikov/SpecificationPattern/blob/master/SpecificationPattern/Specifications.cs

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      You are right, I should have added them to the post in the first place.
      Updated the article, thanks!

  • at

    Agree on this specification pattern. I used this pattern a while back while working on a batch app. Now working on a Web API project. I am trying to avoid duplication too when validating models and domain models. A basic example is in the API/view models where a property is decorated with [EmailAddress] annotation. It gets validated in the API/controller layer which is fine. Now this API/view model will be map to a domain model (using automapper) so it can be passed to the domain services. I need to revalidate the property/properties again in the domain layer before it gets persisted to the database. In the domain layer, it can contain other complex validation that depends on other domain entities and this is where I can apply the specification pattern. I am not sure if specification pattern is best suited for validating attributes (e.g email address, phone number, etc) in the API/controller layer.

  • Patrick Kilgore

    I’m trying to use this as the “where” clause for my repository, but what if I want to pull data from multiple entities? This seems to suggest that I have to limit myself to one entity.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Not necessarily. If your entity has a “navigation property” to other entities, you can use those properties to build corresponding expressions.

      If you provide an example of what you are trying to achieve, I’ll try to see if this use case is possible to implement with the approach described in the article.

      • Richard Lang

        Hi. If Movie had navigation properties of Actor and Director, how would you create a specification for Actor = “Brad Pitt” & Director = “Christopher Nolan”?

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Great question. I would start with as narrow specs as possible. In this case, with these two:


          public class CastingBradPittSpecification : Specification<Movie>
          {
          private const string BradPittName = "Brad Pitt";

          public override Expression<Func<Movie, bool>> ToExpression()
          {
          return movie => movie.Actor.Name == BradPittName;
          }
          }

          public class DirectedByChristopherNolanSpecification : Specification<Movie>
          {
          private const string ChristopherNolanName = "Christopher Nolan";

          public override Expression<Func<Movie, bool>> ToExpression()
          {
          return movie => movie.Director.Name == ChristopherNolanName;
          }
          }

          And then use them in conjunction with each other:


          var spec1 = new CastingBradPittSpecification();
          var spec2 = new DirectedByChristopherNolanSpecification();
          var repository = new MovieRepository();

          IReadOnlyList<Movie> movies = repository.Find(spec1.And(spec2));

          If you don’t need to specify the actor/director names from the outside (UI for example), this would work best. Otherwise, you’d need to introduce more generic specs:


          public class CastingActorSpecification : Specification<Movie>
          {
          private readonly string _actorName;

          public CastingActorSpecification(string actorName)
          {
          _actorName = actorName;
          }

          public override Expression<Func<Movie, bool>> ToExpression()
          {
          return movie => movie.Actor.Name == _actorName;
          }
          }

          public class DirectedBySpecification : Specification<Movie>
          {
          private readonly string _directorName;

          public DirectedBySpecification(string directorName)
          {
          _directorName = directorName;
          }

          public override Expression<Func<Movie, bool>> ToExpression()
          {
          return movie => movie.Director.Name == _directorName;
          }
          }

          Usage:


          var spec1 = new CastingActorSpecification("Brad Pitt");
          var spec2 = new DirectedBySpecification("Christopher Nolan");
          var repository = new MovieRepository();

          IReadOnlyList<Movie> movies = repository.Find(spec1.And(spec2));

          • Richard Lang

            Ah ok. Wasn’t sure if it was necessary to do .Include(“Actor”) and .Include(“Director”) or not.

          • http://enterprisecraftsmanship.com/ Vladimir Khorikov

            Expressions are converted to SQL statements, so no need to retrieve related data to the memory as the filtration will be performed in the database.

          • Aleksandr

            How I can get movies with eager loaded navigation properties Actor and Director ?

          • http://enterprisecraftsmanship.com/ Vladimir Khorikov

            I wouldn’t recommend putting this logic into specs themselves. You’d need to create a separate method in the movie repository that would do .Include() / .Fetch() along with Where(). Like this:

            return session.Query()
            .Where(specification.ToExpression())
            .Fetch(x => x.Actor)
            .Fetch(x => x.Director)
            .ToList();

  • Andriy

    Nice article !

  • Andriy

    Can i use this code in my repository? Thanks in advance

    private IQueryable Match(ISpecification spec, IQueryable source)
    {
    return source.Where(spec.ToExpression());
    }

  • Andriy

    When i try to compose specifications with And() i get an error “The parameter was not bound in the specified LINQ to Entities query expression.”

    • Nicky Salomon Enriquez Torres

      Too i have the same problem, no recognize el second parameter ,

      • Nicky Salomon Enriquez Torres

        Resolved !, in my case mi parameter was bound to together expressions then i apply expression visitor

        internal class ParameterReplacer : ExpressionVisitor
        {
        private readonly ParameterExpression _parameter;

        protected override Expression VisitParameter(ParameterExpression node)
        {
        return base.VisitParameter(_parameter);
        }

        internal ParameterReplacer(ParameterExpression parameter)
        {
        _parameter = parameter;
        }
        }

        Then, change it in the follow bit code :

        public override Expression<Func> ToExpression()
        {
        var _type = typeof(T);
        var parameter = Expression.Parameter(_type, “ru”);//ru or other name
        Expression<Func> leftExpression = _left.ToExpression();
        Expression<Func> rightExpression = _right.ToExpression();

        BinaryExpression andExpression = Expression.AndAlso(
        leftExpression.Body, rightExpression.Body);

        andExpression = (BinaryExpression)new ParameterReplacer(parameter).Visit(andExpression); // line new

        return Expression.Lambda<Func>(
        andExpression, parameter);
        }

        and ok, and thanks for your post vladimir very good now i understand at the 99% specific pattern . Regards from tacna peru

        • Andriy

          Thank you!