Entity Framework Repositories

Posted Thursday, June 10, 2010 by

A long time ago I wrote a few posts about using "Domain Driven Design"-esque repositories using Linq to SQL ("Domain Driven Design Repositories in Linq to SQL"). I still use that general pattern with a few tweaks with extra layer of a "Unit of Work" to manage context lifetimes. I'm using this rebuild as a chance to play with Entity Framework 4 and so need to implement the appropriate interfaces all over again. The only major functionality change will be bringing in support for Entity Frameworks "Include".

I'm not going to go over the full pattern here, just the new parts for Entity Framework, the IRepository interface has changed that GetAll returns an interface IQuery which is pretty much the IQueryable interface with the Include method.

The implementations for IQuery and IRepository are as follows.

public class EntityRepository<T> : IRepository<T> where T : class

{

    private readonly ObjectSet<T> objectSet;

 

    public EntityRepository(ObjectSet<T> objectSet)

    {

        this.objectSet = objectSet;

    }

 

    public IQuery<T> GetAll()

    {

        return new EntityQuery<T>(objectSet);

    }

 

    public void Save(T entity)

    {

        if (entity == null)

            throw new ArgumentNullException("entity");

 

        objectSet.AddObject(entity);

    }

 

    public void Update(T entity)

    {

        if (entity == null)

            throw new ArgumentNullException("entity");

 

        objectSet.Attach(entity);

    }

 

    public void Delete(T entity)

    {

        if (entity == null)

            throw new ArgumentNullException("entity");

 

        objectSet.DeleteObject(entity);

    }

}

public class EntityQuery<T> : IQuery<T>

{

    private readonly ObjectQuery<T> query;

 

    public EntityQuery(ObjectQuery<T> query)

    {

        this.query = query;

    }

 

    public IQuery<T> Include(string path)

    {

        return new EntityQuery<T>(query.Include(path));

    }

 

    IEnumerator<T> IEnumerable<T>.GetEnumerator()

    {

        return ((IEnumerable<T>)query).GetEnumerator();

    }

 

    IEnumerator IEnumerable.GetEnumerator()

    {

        return ((IEnumerable)query).GetEnumerator();

    }

 

    Expression IQueryable.Expression

    {

        get

        {

            return ((IQueryable)query).Expression;

        }

    }

 

    Type IQueryable.ElementType

    {

        get

        {

            return ((IQueryable)query).ElementType;

        }

    }

 

    IQueryProvider IQueryable.Provider

    {

        get

        {

            return ((IQueryable)query).Provider;

        }

    }

}

The actual Repository that gets used by the domain layer simply delegates all it's work back to a internal repository based off the current unit of work. This is important section because it decouples the domain repository from repository doing the actual work and allows me to change the underlying data source if necessary.

public class Repository<T> : IRepository<T> where T : class

{

    private static IRepository<T> Current

    {

        get

        {

            return UnitOfWork.Current.CreateRepository<T>();

        }

    }

 

    public virtual IQuery<T> GetAll()

    {

        return Current.GetAll();

    }

 

    public virtual void Save(T entity)

    {

        if (entity == null)

            throw new ArgumentNullException("entity");

 

        Current.Save(entity);

    }

 

    public virtual void Update(T entity)

    {

        if (entity == null)

            throw new ArgumentNullException("entity");

 

        Current.Update(entity);

    }

 

    public virtual void Delete(T entity)

    {

        if (entity == null)

            throw new ArgumentNullException("entity");

 

        Current.Delete(entity);

    }

}

I'll get into the Unit of Work stuff in my next post.

Simplifying the Composite Specification Pattern

Posted Saturday, March 15, 2008 by

I've found the specification pattern a nice way to wrap up a piece of business rule to be reused through out the application, for instance in our e-commerce product our promotion entity builds a specification based of it's values. We can then use this specification to determine whether an order is valid for the promotion or even filter lists of orders using FindAll method on List and so on. Tim McCarthy has a great article on building Composite Specifications at "A Composite Specification Pattern Implementation in .NET 2.0".

I don't entirely agree with his approach here as I find the leaf specifications he has created such as GreaterThanOrEqualToSpecification in my opinion decrease the readability of the code. While I think it can be argued that you can use these leaf specifications to be build up a richer larger actual domain specification it still means that the creation is difficult to read unless you go about building a fluent interface for the specification (which I have done in the past). You then end up with something like the new NUnit fluent interface.

What I'm going to try and achieve here is a way to bring together easily different domain specifications to create richer ones. The core class behind this is PredicateSpecification, really this is just a utility class that combined with C# lambda expressions gives us some interesting possibilities.

public class PredicateSpecification<T> : Specification<T>

{

    private Predicate<T> predicate;

 

    public PredicateSpecification(Predicate<T> predicate)

    {

        this.predicate = predicate;

    }

 

    public override bool IsSatisfiedBy(T item)

    {

        return predicate(item);

    }

}

 

For something different I've decided to use the &&, || and ! operators to create our composite specifications, this goes along with the theme above that in trying to increase readability we should try and use the readability we already have, i.e: that most C# developers read x && y as "x and y" already so lets not introduce a new concept.

The abstract Specification class is where we're adding our new overloaded operators, and where we use our new PredicateSpecification to combine the two arguments.

public abstract class Specification<T> : ISpecification<T>

{

    public static Specification<T> operator &(Specification<T> left, Specification<T> right)

    {

        return new PredicateSpecification<T>(t => left.IsSatisfiedBy(t) && right.IsSatisfiedBy(t));

    }

 

    public static Specification<T> operator |(Specification<T> left, Specification<T> right)

    {

        return new PredicateSpecification<T>(t => left.IsSatisfiedBy(t) || right.IsSatisfiedBy(t));

    }

 

    public static Specification<T> operator !(Specification<T> specification)

    {

        return new PredicateSpecification<T>(t => !specification.IsSatisfiedBy(t));

    }

 

    public static bool operator true(Specification<T> specification)

    {

        return false;

    }

 

    public static bool operator false(Specification<T> specification)

    {

        return false;

    }

 

    public abstract bool IsSatisfiedBy(T item);

}

 

And here's some tests to show it working.

[TestFixture]

[TestsOn(typeof(Specification<>))]

public class SpecificationFixture

{

    [Test]

    public void NotOperatorIsOverloaded()

    {

        PredicateSpecification<string> lengthSpecification = new PredicateSpecification<string>(s => s.Length >= 5 && s.Length <= 10);

        ISpecification<string> specification = !lengthSpecification;

 

        Assert.IsTrue(specification.IsSatisfiedBy("a"));

        Assert.IsFalse(specification.IsSatisfiedBy("123456"));

    }

 

    [Test]

    public void AndOperatorIsOverloaded()

    {

        PredicateSpecification<int> lessThan10 = new PredicateSpecification<int>(i => i < 10);

        PredicateSpecification<int> moreThan5 = new PredicateSpecification<int>(i => i > 5);

 

        ISpecification<int> compositeSpecification = lessThan10 && moreThan5;

 

        Assert.IsTrue(compositeSpecification.IsSatisfiedBy(7));

        Assert.IsFalse(compositeSpecification.IsSatisfiedBy(3));

        Assert.IsFalse(compositeSpecification.IsSatisfiedBy(13));

    }

 

    [Test]

    public void OrOperatorIsOverloaded()

    {

        PredicateSpecification<int> moreThan10 = new PredicateSpecification<int>(i => i > 10);

        PredicateSpecification<int> lessThan5 = new PredicateSpecification<int>(i => i < 5);

 

        ISpecification<int> compositeSpecification = lessThan5 || moreThan10;

 

        Assert.IsFalse(compositeSpecification.IsSatisfiedBy(7));

        Assert.IsTrue(compositeSpecification.IsSatisfiedBy(3));

        Assert.IsTrue(compositeSpecification.IsSatisfiedBy(13));

    }

}

 

Let me know what you think.

Specialised LINQ to SQL Repositories

Posted Saturday, February 9, 2008 by

 We finished off last time with creating a Repository<T> class and matching interface. This is a general workhorse of a class that allows such syntax as

IRepository<Item> repository = new Repository<Item>(new InMemoryUnitOfWork);
IEnumerable<Item> outOfStock = from i in repository where i.QuantityOnHand == 0 select i;
foreach(Item item in repository) { }

What I'd like however is to be able to encapsulate some of the more complex queries behind specialised repositories, these repositories can can then mocked with tools other than TypeMock and move some great interaction based testing. We'll start by moving the out of stock query above to an ItemRepository

public interface IItemRepository
{
IEnumerable<Item> GetOutOfStockItems();
}
public class ItemRepository : Repository<Item>, IItemRepository
{
public ItemRepository(IUnitOfWork unitOfWork) : base(unitOfWork) { }
public IEnumerable<Item> GetOutOfStockItems()
{
return outOfStock = from i in this where i.QuantityOnHand == 0 select i;
}
}

The LINQ query does look a little odd since we're querying the repository directly, in order to make this a little more readable I add a property

IQueryable<Item> Items
{
get { return this; }
}

to make the LINQ query

from i in Items where i.QuantityOnHand == 0 select i;

Interestingly because IItemRepository doesn't implement IRepository<Item> we lose externally the ability to execute LINQ queries against it (this could be desired through). I prefer altering it however to

public interface IItemRepository : IRepository<Item>

in order the use of LINQ and normal repository actions throughout the system while only refactoring complex or commonly used queries into the repository itself.

Domain Driven Design Repositories in LINQ to SQL

Posted Tuesday, February 5, 2008 by

Lately I've been working with NHibernate behind a domain driven design style repository interface, this allows for easily testability as I can create mock repositories using Rhino Mocks and give my services prepackaged results for testing purposes.

This has worked out great, in combination with NHibernate Query Generator I get some very readable code. After deciding that my next pet project would include LINQ to SQL I wanted to achieve the same results with regard to testability without reliance on an external database.

From some reading around the web it looked like doing interaction style testing on LINQ style queries would be difficult due to extension methods being static and the like (I realise TypeMock gets around this due to using the Profiler API rather than dynamic proxies). But at the minimum I wanted to provide prepackaged results and the ability to create aggregate repositories with specialised queries that could be mocked and tested.

This really isn't persistence ignorance as our model is still tied LINQ to SQL via the attributes, but I still achieve some worthwhile goals even if I'm not being completely ignorant.

The two best pieces of work I could find on the subject were K. Scott Allen's "Trying Out Persistence Ignorance With LINQ" and "Being Ignorant with LINQ to SQL" by Ian Cooper. I preferred the formers approach the best and really this work is just wrapping up his work with some personal alterations.

LINQ queries work by a QueryProvider resolving an expression, LINQ to SQL resolves the expression to SQL whereas something like LINQ to Amazon resolves the same expression to a web-service call. In order to achieve our testing goals the QueryProvider that ultimately resolves the given expression is switched. For our in-memory repository we'll be using a List<T> and therefore LINQ to Objects.

We begin by defining out IUnitOfWork, this will create data sources that will represent either a table in LINQ to SQL or a List<T> in LINQ to Objects as well as provide a life cycle for our underlying DataContext. Our InMemoryUnitOfWork is storing it's created data sources so that repeated creations of a data source will always have the same underlying list to mimic the behavior of our SqlUnitOfWork which is always using the same DataContext.

public interface IUnitOfWork : IDisposable
{
IDataSource<T> GetDataSource<T>() where T : class;
void SubmitChanges();
}
public class InMemoryUnitOfWork : IUnitOfWork
{
private Hashtable dataSources = new Hashtable();
public IDataSource<T> GetDataSource<T>() where T : class
{
if(!dataSources.ContainsKey(typeof(T)))
dataSources.Add(typeof(T), new InMemoryDataSource<T>());
return dataSources[typeof(T)] as InMemoryDataSource<T>;
}
public void SubmitChanges()
{
}
public void Dispose()
{
}
}
public class SqlUnitOfWork : IUnitOfWork
{
private DataContext context;
public SqlUnitOfWork(DataContext context)
{
if(context == null)
throw new ArgumentNullException("context");
this.context = context;
}
public IDataSource<T> GetDataSource<T>() where T : class
{
return new SqlDataSource<T>(context);
}
public void SubmitChanges()
{
context.SubmitChanges();
}
public void Dispose()
{
context.Dispose();
}
}

Now to define our IDataSource, it inherits IQueryable<T> to allow it to be queried using LINQ. Part of the IQueryable<T> interface is the property Provider, each data source will route all LINQ queries to their underlying Provider to be appropriately resolved. I've also defined some simple Save, Update and Delete methods, I'm doing this rather than implementing something like ITable because I want to keep the repository simple and fairly similar to NHibernate.

public interface IDataSource<T> : IQueryable<T> where T : class
{
void Update(T entity);
void Update(IEnumerable<T> entities);
void Delete(T entity);
void Delete(IEnumerable<T> entities);
void Save(T entity);
void Save(IEnumerable<T> entities);
}
public class InMemoryDataSource<T> : IDataSource<T> where T : class
{
private List<T> dataSource;
public InMemoryDataSource()
: this(new List<T>())
{
}
public InMemoryDataSource(List<T> dataSource)
{
if(dataSource == null)
throw new ArgumentNullException("dataSource");
this.dataSource = dataSource;
}
public IEnumerator<T> GetEnumerator()
{
return dataSource.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public Type ElementType
{
get
{
return dataSource.AsQueryable<T>().ElementType;
}
}
public Expression Expression
{
get
{
return dataSource.AsQueryable<T>().Expression;
}
}
public IQueryProvider Provider
{
get
{
return dataSource.AsQueryable<T>().Provider;
}
}
public void Delete(T entity)
{
dataSource.Remove(entity);
}
...
}
public class SqlDataSource<T> : IDataSource<T> where T : class
{
private Table<T> table;
public SqlDataSource(DataContext context)
{
if(context == null)
throw new ArgumentNullException("context");
table = context.GetTable<T>();
}
public IEnumerator<T> GetEnumerator()
{
return table.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public Type ElementType
{
get
{
return table.AsQueryable<T>().ElementType;
}
}
public Expression Expression
{
get
{
return table.AsQueryable<T>().Expression;
}
}
public IQueryProvider Provider
{
get
{
return table.AsQueryable<T>().Provider;
}
}
public void Delete(T entity)
{
table.DeleteOnSubmit(entity);
}
...
}

An IRepository<T> is simply another data source but I've created this interface anyway in order to keep everything linked up with domain driven design concepts and for future extensions. I've now also created a base Repository<T> class that takes a given IUnitOfWork and then uses it's given data source for all it's operations. We can NOW create a repository with an in memory data source, add items to it before passing it to services under test. While in our live system use a LINQ to SQL DataContext to send all our queries to SQL Server.

public interface IRepository<T> : IDataSource<T> where T : class
{
}
public class Repository<T> : IRepository<T> where T : class
{
private IDataSource<T> dataSource;
public Repository(IUnitOfWork unitOfWork)
{
if(unitOfWork == null)
throw new ArgumentNullException("unitOfWork");
dataSource = unitOfWork.GetDataSource<T>();
}
public void Update(T entity)
{
dataSource.Update(entity);
}
public void Update(IEnumerable<T> entities)
{
dataSource.Update(entities);
}
public void Delete(T entity)
{
dataSource.Delete(entity);
}
public void Delete(IEnumerable<T> entities)
{
dataSource.Delete(entities);
}
public void Save(T entity)
{
dataSource.Save(entity);
}
public void Save(IEnumerable<T> entities)
{
dataSource.Save(entities);
}
public IEnumerator<T> GetEnumerator()
{
return dataSource.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public Type ElementType
{
get
{
return dataSource.ElementType;
}
}
public Expression Expression
{
get
{
return dataSource.Expression;
}
}
public IQueryProvider Provider
{
get
{
return dataSource.Provider;
}
}
}
[Test]
public void LinqQueryFromInMemoryUnitOfWork()
{
IRepository<Item> repository = new Repository<Item>(new InMemoryUnitOfWork());
repository.Save(new Item() { Name = "Item1", QuantityOnHand = 10 });
repository.Save(new Item() { Name = "Item2", QuantityOnHand = 0 });
IEnumerable<Item> outOfStockItems = from item in repository where item.QuantityOnHand == 0 select item;
CollectionAssert.AreCountEqual(1, outOfStockItems.ToList());
}

Once I get some appropriate hosting sorted out I'll post the full code and unit tests. Next time, creating specialised aggregate repositories...

Page 1 of 11

Professional Windows App Development