In my previous post I put down some thoughts on the Repository and Specification patterns and in the end said that with the introduction of Linq and the growing popularity of ORM frameworks and their support for Linq, it’s time to look back at these two patterns and see how we can leverage Linq to simplify the patterns and make them infrastructure agnostic.

The goal of this post is to implement infrastructure for a Repository and Specification pattern that achieves the following goals:

  1. We should be able to execute Linq queries directly against the repository.
  2. Implement a specification pattern that allows us to use Expressions as predicates for the specifications.
  3. Implement a specification pattern than allows us to combine specifications (Composite Specification Pattern)
  4. We should be able to query the repository using the Specification pattern.
  5. We should be able to execute Linq queries against the repository directly and also combine the query with specifications.

Creating a base class for all Repositories:

With the above goals the first thing is to start implementing a base Repository interface:

    public interface IRepository<T> : IQueryable<T>

    {

        void Save(T entity);

 

        void Remove(T entity);

    }

The IRepository interface also implements the IQueryable interface allowing us to execute Linq queries directly on the repository. Most repository implementations also have a Load or a Get method that takes in an ID that the repository uses to load the entity. In this case I have omitted those functions since they can be easily represented by Linq queries.

The next step is to implement an abstract base class to make it easy for creating different implementations of the IRepository interface:

    public abstract class RepositoryBase<T> : IRepository<T>

    {

 

    }

So the first thing is to add the Save and Remove methods to the RepositoryBase class as abstract methods. This will allow the child classes to implement the actual functionality of Saving and Removing the entities from the repository:

        #region Implementation of IRepository<T>

        public abstract void Save(T entity);

 

        public abstract void Remove(T entity);

        #endregion

Next we add abstract property to the base class allowing the child class to pass in a IQueryable instance that the base class will use to implement the IQuerable interface:

    public abstract class RepositoryBase<T> : IRepository<T>

    {

        protected abstract IQueryable<T> RepositoryQuery { get;}

Now we can implement members of the IQueryable interface and basically just delegate the calls for IQueryable to the IQuerable isntance that the RepositoryQuery provides us:

        #region Implementation of IEnumerable

        /// <summary>

        /// Returns an enumerator that iterates through the collection.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>1</filterpriority>

        public IEnumerator<T> GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

 

        /// <summary>

        /// Returns an enumerator that iterates through a collection.

        /// </summary>

        /// <returns>

        /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>2</filterpriority>

        IEnumerator IEnumerable.GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

        #endregion

 

        #region Implementation of IQueryable

        /// <summary>

        /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable" />.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.Expressions.Expression" /> that is associated with this instance of <see cref="T:System.Linq.IQueryable" />.

        /// </returns>

        public Expression Expression

        {

            get { return RepositoryQuery.Expression; }

        }

        /// <summary>

        /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable" /> is executed.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Type" /> that represents the type of the element(s) that are returned when the expression tree associated with this object is executed.

        /// </returns>

        public Type ElementType

        {

            get { return RepositoryQuery.ElementType; }

        }

        /// <summary>

        /// Gets the query provider that is associated with this data source.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.IQueryProvider" /> that is associated with this data source.

        /// </returns>

        public IQueryProvider Provider

        {

            get { return RepositoryQuery.Provider; }

        }

        #endregion

Here’s the full code for the RepositoryBase class:

    public abstract class RepositoryBase<T> : IRepository<T>

    {

        protected abstract IQueryable<T> RepositoryQuery { get;}

 

        #region Implementation of IRepository<T>

        public abstract void Save(T entity);

 

        public abstract void Remove(T entity);

        #endregion

 

        #region Implementation of IEnumerable

        /// <summary>

        /// Returns an enumerator that iterates through the collection.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>1</filterpriority>

        public IEnumerator<T> GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

 

        /// <summary>

        /// Returns an enumerator that iterates through a collection.

        /// </summary>

        /// <returns>

        /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>2</filterpriority>

        IEnumerator IEnumerable.GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

        #endregion

 

        #region Implementation of IQueryable

        /// <summary>

        /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable" />.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.Expressions.Expression" /> that is associated with this instance of <see cref="T:System.Linq.IQueryable" />.

        /// </returns>

        public Expression Expression

        {

            get { return RepositoryQuery.Expression; }

        }

        /// <summary>

        /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable" /> is executed.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Type" /> that represents the type of the element(s) that are returned when the expression tree associated with this object is executed.

        /// </returns>

        public Type ElementType

        {

            get { return RepositoryQuery.ElementType; }

        }

        /// <summary>

        /// Gets the query provider that is associated with this data source.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.IQueryProvider" /> that is associated with this data source.

        /// </returns>

        public IQueryProvider Provider

        {

            get { return RepositoryQuery.Provider; }

        }

        #endregion

    }

We can now use this base class to implement child classes and meet our first requirement where we should be able to execute Linq queries directly on the repository. Below are two implementations, one is a Repository that uses a In memory list of Persons while another is a repository that uses a Linq to SQL DataContext (Note: Ideally the DataContext should not be created by the Repository but instead it should either get the DataContext through dependency injection or through a service locator, but for this example creating the DataContext should suffice):

    public class InMemoryPersonRepository : RepositoryBase<Person>

    {

        private List<Person> _persons = new List<Person>();

 

        #region Overrides of RepositoryBase<Person>

        protected override IQueryable<Person> RepositoryQuery

        {

            get { return _persons.AsQueryable(); }

        }

        public override void Save(Person entity)

        {

            _persons.Add(entity);

        }

 

        public override void Remove(Person entity)

        {

            _persons.Remove(entity);

        }

        #endregion

    }

 

    public class LinSqlPersonRepository : RepositoryBase<Person>

    {

 

        private ClassScheduleDataContext _context = new ClassScheduleDataContext();

 

        #region Overrides of RepositoryBase<Person>

        protected override IQueryable<Person> RepositoryQuery

        {

            get { return _context.Persons.AsQueryable(); }

        }

        public override void Save(Person entity)

        {

            _context.Persons.InsertOnSubmit(entity);

        }

 

        public override void Remove(Person entity)

        {

            _context.Persons.DeleteOnSubmit(entity);

        }

        #endregion

    }

So now it’s fairly simple to execute Linq queries directly on the repository:

        public static void Main(string[] args)

        {

            IRepository <Person> repository = new InMemoryPersonRepository();

            var results = from person in repository

                          where person.LastName.Contains("Doe")

                          select person;

        }

Creating a Specification class that allows using Expressions as predicates:

Okay, the next three requirements deal with implementing a Specification pattern that will allow us to use Lambda expressions as predicate. So starting with the interface:

    public interface ISpecification<T>

    {

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

 

        bool IsSatisfiedBy(T entity);

    }

The ISpecificaiton interface has one property Predicate that should return the expression that the specification uses. Now that we have an interface, lets create a generic Specification class that allows creating specification instances:

    public class Specification<T> : ISpecification<T>

    {

        private readonly Expression<Func<T, bool>> _predicate;

 

        public Specification(Expression<Func<T, bool>> predicate)

        {

            _predicate = predicate;

        }

 

        public Expression<Func<T, bool>> Predicate

        {

            get { return _predicate; }

        }

 

        public bool IsSatisfiedBy(T entity)

        {

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

        }

    }

So far so good… the Specification class basically takes in an Expression of Func<T, bool> that it stores in the _predicate field, which it then invokes in IsSatisfiedBy to check if a entity satisfies the specification. Now the third requirement is to allow composing specifications. To provide a clean framework, I’m going to use some operator overloading logic and overload the & and | operators on Specification class:

        public static Specification<T> operator & (Specification<T> leftSide, Specification<T> rightSide)

        {

            var rightInvoke = Expression.Invoke(rightSide.Predicate, leftSide.Predicate.Parameters.Cast<Expression>());

            var newExpression = Expression.MakeBinary(ExpressionType.AndAlso, leftSide.Predicate.Body, rightInvoke);

            return new Specification<T>(

                                    Expression.Lambda<Func<T, bool>>(newExpression, leftSide.Predicate.Parameters)

                                  );

 

        }

 

        public static Specification<T> operator | (Specification<T> leftSide, Specification<T> rightSide)

        {

            var rightInvoke = Expression.Invoke(rightSide.Predicate, leftSide.Predicate.Parameters.Cast<Expression>());

            var newExpression = Expression.MakeBinary(ExpressionType.OrElse, leftSide.Predicate.Body, rightInvoke);

            return new Specification<T>(

                                    Expression.Lambda<Func<T, bool>>(newExpression, leftSide.Predicate.Parameters)

                                  );

        }

What the overloads does is it takes two specifications that need to be combined and creates a new BinaryExpression of the appropriate expression type, that is OrElse or AndAlso, and then returns a new Specification that uses the BinaryExpression as it’s predicate. We can now use the Specification class like so to define our specifications:

    public class CustomerSpecifications

    {

        public Specification<Customer> IsPreferred

        {

            get

            {

                return new Specification<customer>(customer => customer.AverageInvoice > 100000 &&

                                                               customer.AverageQty > 1000);

            }

        }

 

        public Specification<Customer> BuysPremiumPaper

        {

            get

            {

                return new Specification<Customer>(customer => customer.PaperOrdered

                                                                    .Where(paper => paper.Premium == true)

                                                                    .Count() > 100);

            }

        }

    }

And use the above specifications in a Customer entity like so:

    public class Customer

    {

        public bool IsPreferredAndBuysPremium

        {

            get

            {

                return (CustomerSpecifications.IsPreferred &

                        CustomerSpecifications.BuysPremiumPaper).IsSatisfiedBy(this);

            }

        }

 

    }

Integrating the Specification class with RepositoryBase:

Now that we have a way to define re-usable business logic by the way of specifications, lets integrate the Specification class with the RepositoryBase class to allow querying the repository using specifications. First thing is to modify the IRepository interface and add a Query method to it so that returns an IQueryable based on executing the provided specification:

    public interface IRepository<T> : IQueryable<T>

    {

        void Save(T entity);

 

        void Remove(T entity);

 

        IQueryable<T> Query(ISpecification<T> specification);

    }

Next is to implement the Query method on the RepositoryBase class:

        public IQueryable<T> Query(ISpecification<T> specification)

        {

            return RepositoryQuery.Where(specification.Predicate);  

        }

What the Query implementation does is basically uses the Where Linq extension to add the predicate provided by the specification to the IQueryable instance. Now with that done the last two requirements are also complete. Below is an example that shows the various ways we can now use the RepositoryBase and Specification classes to query the repository flexibly:

        public static void Main(string[] args)

        {

            var allCustomersInStateCA = from customer in new CustomersRepository()

                                       where customer.State == "CA"

                                       select customer;

 

            var preferredCustomers = new CustomerRepository.Query(CustomerSpecifications.IsPreferred);

            var preferredCustomersInCA = from customer in preferredCustomers

                                        where customer.State == "CA"

                                        select customer;

 

            var prefferedPremiumCustomers = new CustomerRepository().Query(CustomerSpecifications.IsPreferred &

                                                                          CustomerSpecifications.BuysPremiumPaper);

            var prefferedPremimumCustomersInCA = from customer in prefferedPremiumCustomers

                                                where customer.State == "CA"

                                                select customer;

        }

The above implementation now satisfies all the goals I had set out for the Repository and Specification implementation. I’ve added similar implementations to Rhinestone, so if you would like to get complete source code of the RepositoryBase and Specification classes check out Rhinestone’s source code: http://code.google.com/p/rhinestone/source/checkout.

Posted on Wednesday, August 13, 2008 5:20 PM | Filed Under [ Patterns DDD Repository Architecture ]


Comments

Gravatar
# Thank you so much for this Specification pattern i...
Posted by Anonymous
on 8/19/2010 9:19 AM
Thank you so much for this Specification pattern implementation. It's one of the best things I've learnt for weeks. I'm gonna get busy with it right now!

David
Gravatar
# Thank you for the great post!
Posted by Роман
on 7/4/2010 2:53 PM
Thank you for the great post!
Gravatar
# LinqToSql allow to map store procedure. Do you hav...
Posted by cortex
on 3/1/2010 12:25 PM
LinqToSql allow to map store procedure. Do you have any idea how we can abstract those using Specification pattern.
What I would want is a query pattern that will be transparent weither it use a sp or a linq query to retrieve elements. That way, if some linq query specification need to be optimised through sp, it would not break client code.
Gravatar
# It&#39;s a great idea, but don&#39;t think this wi...
Posted by Anonymous
on 1/11/2010 3:37 PM
It's a great idea, but don't think this will work for many persistence frameworks. Not everything is supporting IQueryable, which would render the specification pattern very problematic. This is one of the drawbacks of the repository pattern. You simply cannot please all. Unless, of course, you don't have a problem with bloated repositories with hundreds of GetEntityBy{Fill In The Blank} for larger models.
Gravatar
# @James: It's possible using closures and paramete...
Posted by Ritesh Rao
on 5/20/2009 4:01 PM
@James:

It's possible using closures and parameterized specifications. Send me an email so that I can reply back with a sample you can take a look at. Posting a reply here's going to take too much effort.
Gravatar
# Ritesh, I'm really fascinated by the NCommon libr...
Posted by James
on 5/20/2009 2:53 PM
Ritesh,

I'm really fascinated by the NCommon library, and am working through using your implementation of Specification but I've run into a possible downside of the abstraction. I'd like to get as close to a fully compiled query as possible and also allow passing in parameters. This is relatively easy to do in a non-abstracted way, but when I introduce IRepository and ISpecification I lose the simplicity of a single compiled query and need to gen up a new specification for each parameter value I'm passing in. So it's compile once, use alot, or compile alot and use once each. Is there any way you can imagine to work through this?

Thanks so much,

James
Gravatar
# Hi Ritesh,<br><br>Many thanks for this. Very inte...
Posted by Michael
on 1/31/2009 8:57 PM
Hi Ritesh,

Many thanks for this. Very interesting ideas and you write and code in an easy to follow manner.

I do have one question, if I may. It's regarding the IsPreferred specification for the customer. This looks at two things (Average Invoice value and Average Quantity) to determine if the customer IsPreferred. Imagine that these values weren't persisted in the database and that I was calculating them on my object (let's leave aside the horrible performance :-)), how would the repository know how to query average invoice and average quantity?

Don't we actually need some kind of translation within the repository from the language of the domain into the language of the query / persistence? If you don't, doesn't this mean that while your entities are persistence ignorant, your specifications are not?

Again, many thanks for the series. It's fascinating stuff and I'm learning tons!

Cheers,
Michael
Gravatar
# It's so nice to see practical implementations of t...
Posted by James
on 12/2/2008 2:45 PM
It's so nice to see practical implementations of these ideas, thanks so much for your hard work and for supporting the .NET community!
Gravatar
# Outside the box:<br>Thanks for pointing the bug ou...
Posted by Ritesh Rao
on 8/19/2008 4:43 PM
Outside the box:<BR/>Thanks for pointing the bug out on Specification class. I have fixed the issue and checked in the changes.<BR/><BR/>-------------------------------------<BR/>Everyone that requested a sample to show how the RepositoryBase would be used when using Linq to SQL, please see my latest blog post: www.codeinsanity.com/.../>Thank you for your comments again! Keep em coming!
Gravatar
# I wrote a series of articles very similar to this ...
Posted by berko
on 8/17/2008 11:06 PM
I wrote a series of articles very similar to this here - www.mostlyclean.com/.../>The implementation shown here is interesting but I am slightly concerned about my Repository implementing IQueryable. I think this is a little 'leaky' but there are clearly some nice benefits from doing so.
Gravatar
# I posted this on your first post. Sorry about tha...
Posted by Outside The Box
on 8/17/2008 9:13 PM
I posted this on your first post. Sorry about that... <BR/><BR/>I got your code from subversion and there was not a test in there for the Repository or specification. I would like to see it being used. Can you create a unit test for it with your example? I copied your code but it wouldn't compile. The specification had errors.<BR/><BR/>Love the blog - Thanks.
Gravatar
# nick / eric:<br><br>Thanks for you comments. I'm f...
Posted by Ritesh Rao
on 8/17/2008 3:31 PM
nick / eric:<BR/><BR/>Thanks for you comments. I'm following up this post with a more complete example that tackles persistence using Unit Of Work and DDD designs.<BR/>-----------------------------------<BR/><BR/>tom:<BR/>Again I will be posting a complete example of DDD, PI, Repository and Unit Of Work shortly using the RepostitoryBase as a base for my repositories. <BR/><BR/>Regarding you question on being able to use EF and now pollute the Domain, that is not possible in v1 of EF. v2.0 of EF under development is definitely addressing the POCO issue but for now I wouldn't recommend using EF especially if you have a DDD design.<BR/><BR/>As for you observation that "speficitation objects are the only objectst that interact with a linq provider so this woul be were the changes are when swtiching to another O/R Mapper"... that is not entirely correct. The specification objects are not tied to any implementation to IQueryable or IQueryProvuder at all. Instead they use Lambda expressions to express their predicates which can then be used by POCO objects or by repositories. The RepositoryBase is responsible of translating the Specification object to a query but the specification object itself doesn't depend on the a linq query.
Gravatar
# The developer team that I am part of is trying to ...
Posted by Tom Pester
on 8/17/2008 12:50 PM
The developer team that I am part of is trying to come up with an DDD architecure that is truely persistant ignorant.<BR/><BR/>We love the expressivness of linq and would like to use it inside of our repositories and also outside of them in a ad hoq manner.<BR/><BR/>NHibernate has a linq provider under development and because it's not final yet we tried using the Entity Framework and see if we could come up with an architecture where we could easily swap out Entity Framwork for NHibernate or even LLBLGen without affecting our domain and as a consequence the client code that is consuming our domain.<BR/><BR/>At the end we come to the conclusion that if we use the Entity Framework our Domain would be poluted with things specific to EF. This is because EF does not support a POCO approach.<BR/><BR/><BR/>This artcile discusses the repository part of DDD which was helpful but what about peristance/Unit Of Work?<BR/><BR/>Is there a DDD architecure possible that uses the EF in its repositories but does not polute the rest of the Domain? With polution I mean that there is something specific to the EF in the domain that would make it immpossible to swap EF for NHibernate without rewriting some of the domain.<BR/><BR/>Also, after reading your post about the specification pattern, I believe that the speficitation objects are the only objectst that interact with a linq provider so this woul be were the changes are when swtiching to another O/R Mapper.<BR/><BR/>I also recommend Eric Evans book about DDD although its not a light reading book. Can we exchange some thoughts about this book Ritesh? I only read it once and not all of the ideas have settled in my mind. I would love to discuss them with you. My email is tomDOTpesterATtelenetREMOVVETHIS.be
Gravatar
# Hi Ritesh,<br><br>Can you demonstrate how this wou...
Posted by Nick
on 8/16/2008 3:16 PM
Hi Ritesh,<BR/><BR/>Can you demonstrate how this would be implemented against LINQ to SQL, so that it can be testable with unit tests.<BR/><BR/>Because besides adding a few business rules which can really be accomplished by implementing the partial class of one of the LINQ objects. I don't see how this really advances LINQ to SQL. It seems to just add another unnecessary layer. I feel this way because I am still forced in to using a database representation of my object model instead of a domain representation. In addition to that I have to test my business rules against the database model, instead of the domain model where I really want to test.<BR/><BR/>I love the idea of separating out business specs, but I guess I need a little more glue so that I can figure out how to use this with domain objects.
Gravatar
# Maybe I'm missing something - What using this mode...
Posted by Erik
on 8/15/2008 10:53 PM
Maybe I'm missing something - What using this model is responsible for actually persisting these objects? Also, how are relationships between objects modeled and interacted with?
Gravatar
# skain:<br><br>The LinqSqlPersonRepository is a con...
Posted by Ritesh Rao
on 8/15/2008 9:16 PM
skain:<BR/><BR/>The LinqSqlPersonRepository is a contrived example that should not be considered as guidance on creating Linq To SQL Repositories. I also mention in the post that the DataContext should not really be created by the repository anyway.<BR/><BR/>I completely agree that the correct way to get the underlying DataContext is to use the Unit of Work Pattern, and you could easily create a child of RepositoryBase that uses the unit of work pattern to get the current DataContext, but for the purpose of this post I felt introducing another pattern would just be confusing if the unit of work pattern was just mentioned in passing.<BR/><BR/>I will be discussing the unit of work pattern in detail in a future post.
Gravatar
# Wow... Very nice - thanks for posting this!
Posted by Erik
on 8/15/2008 8:29 PM
Wow... Very nice - thanks for posting this!
Gravatar
# You're not disposing of your data contexts as far ...
Posted by skain
on 8/15/2008 8:24 PM
You're not disposing of your data contexts as far as I can see with this method. MS is quite clear that a data context is not meant to be persisted. It should only exist long enough to perform one 'unit of work'.<BR/><BR/>I don't see why you would ignore this guidance just to satisfy some idealistic design pattern.
Gravatar
# this is outstanding! Thank you very much!
Posted by Anonymous
on 8/15/2008 1:54 PM
this is outstanding! Thank you very much!
Gravatar
# re: Implementing Repository and Specification patterns using Linq
Posted by trusted essay
on 7/16/2012 9:28 AM
I already used some of the links you posted here for SDET position and I want to say thank you for always giving us the best written blogs. :)
Gravatar
# re: Implementing Repository and Specification patterns using Linq
Posted by DateJust
on 1/17/2013 2:19 AM
This specific auto/mechanical chronograph, certainly more than any, is definitely glamorous boardroom discussion instrument. In rolex replica actual fact, these kinds of high end watches possibly ought to have to Rolex Day Date participate that rite regarding penetration with regard to jr professionals every time they acquire its tips into the hair extensions executive washroom.
Post Comment
Title *
Name *
Email
Url
Comment *  
Please add 5 and 5 and type the answer here: