Linq Expressions, The Specification Pattern and Repositories - Part 2

In Part 1 of this series I expressed my goal of a powerful Linq implementation for the specifications within my domain. In this part of the series I go into further detail and show I have implemented my repositories to support the pattern.

The IRepository definition

In the code below I have restricted my IRepository to be read-only for the purposes of the exercise. Obviously in reality there would be more functionality defined on this interface.

The use of the specification as a parameter to the Find methods is obvious. The use of an Expression is not so obvious at this stage and I will elaborate on this functionality later in the series.

    public interface IRepository<T> where T : IEntity
    {
        T FindOne(Guid id)
;
        
T FindOne(Expression<Func<T, bool>> expression);
        
T FindOne(Specification<T> specification);

        
IQueryable<T> FindAll();
        
IQueryable<T> FindAll(Expression<Func<T, bool>> expression);
        
IQueryable<T> FindAll(Specification<T> specification);
    
}

The Repository

Implementing the repository means tying oneself to a particular Linq provider. In my case I chose Linq to NHibernate but switching it out for another implementation should be trivial.

See in the repository implementation that work is able to be integrated with the specifications by calling either SatisfyElementFrom (FindOne) of SatisfyElementsFrom (FindAll) and providing a candidate parameter provided by the Linq provider - in this case Linq to NHibernate provides a Queryable list proxy when we specify session.Linq().

    public class Repository<T> : IRepository<T> where T : IEntity
    {
        
private readonly ISession session;

        public 
Repository(ISession session)
        {
            
this.session session;
        
}

        
public T FindOne(Guid id)
        {
            
return session.Get<T>(id);
        
}

        
public T FindOne(Expression<Func<T, bool>> expression)
        {
            
return FindOne(new AdHoc<T>(expression));
        
}

        
public T FindOne(Specification<T> specification)
        {
            
return specification.SatisfyingElementFrom(session.Linq<T>());
        
}

        
public IQueryable<T> FindAll()
        {
            
return (from t in session.Linq<T>() select t);
        
}

        
public IQueryable<T> FindAll(Expression<Func<T, bool>> expression)
        {
            
return FindAll(new AdHoc<T>(expression));
        
}

        
public IQueryable<T> FindAll(Specification<T> specification)
        {
            
return specification.SatisfyingElementsFrom(session.Linq<T>());
        
}
    }

Conclusion

In this article I have shown an implementation of my repository facilitated by the use of Linq to NHibernate. The most striking part is the simplicity of the code. We have nicely seperated out our query concerns and the repository provides us with flexibility and also efficiency thanks to the power of Linq.

kick it on DotNetKicks.com

August 12, 2008 12:16 by steven.burman
E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Related posts

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

July 4. 2009 20:18