DataContext Repository Pattern Example Code

An entry about linq | design patterns Publication date 27. September 2008 11:25

Since writing my post on abstracting the Linq to Sql DataContext, I’ve had several requests to post an example project which shows exactly how this works. I finally found some time to do just that – click here to download it!

In the zip file you’ll find the Devin.Core project (Devin is the name of a small start-up I’m involved in), which contains the current version of my DataContext abstraction, as well as the specification pattern implementation that I’ve written about earlier (which by the way is not really finished yet – I’m still planning to pursue this further when I get some time).

To show how it works, I’ve included a simple console application that you can play with.

Currently rated 5.0 by 15 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Linq, the Specification Pattern and Encapsulation

An entry about linq Publication date 12. July 2008 15:08

Nicholas Blumhardt (author of Autofac) recently wrote about how Linq can significantly simplify the implementation of the Specification Pattern. He covered the topic excellently, so I won’t regurgitate it here; instead I suggest you go read his post before reading this one.

Done? Cool. One of the downsides Nicholas mentions, is how using the specification pattern can, to a certain degree, break the encapsulation of entities in the domain model.

Disclaimer: Consider this post as a proof of concept. Whether or not the ideas presented here within actually represents something viable, is yet to be seen.

In his Loan class, he has a method IsOverdue:

public bool IsOverdue()
{
    return new OverdueLoanSpecification().IsSatisfiedBy(this);
}

 

Now, imagine we have a web application that uses this method to display either a red or green flag next to each row in a table of loans:

<% foreach (Loan loan in this.ViewData) {%>
    <tr>
        <td>
            <%= loan.IsOverdue() ? 
                Html.Image("~/Content/Icons/red_flag.png") : 
                Html.Image("~/Content/Icons/green_flag.png") %>
        </td>
        <td><%= loan.Book.Title %></td>
        <td><%= loan.DateBorrowed %></td>
        <td><%= loan.DateDue %></td>
        <td><%= loan.DateReturned %></td>
    </tr>        
<%}%>

 

Somewhere else in this application, there might be a method that needs to get all the overdue books from the repository (for some other purpose). There, we might see the following code:

var specification = new OverdueLoanSpecification();
var overdueLoans = dataContext.FindBySpecification(specification);

 

What happened here, is that we broke the encapsulation of the Loan class. What would have been preferable, is this:

var overdueLoans = from loan in loanRepository where loan.IsOverdue() select loan;

 

Such a query has a major problem though: It cannot be executed against a database, because the database will have no idea what IsOverdue means. More precisely, the ORM (in my case Linq to Sql) will have no idea how to translate IsOverdue into SQL. But maybe we can help it? What if we hijack the query expression before it is passed to the ORM, and replace the IsOverdue method call with the specification directly?

For this to work, we need to define specifications as expressions, so that a specification might look something like this:

public class OverdueLoanSpecification : Specification<Loan>
{
    protected override Expression<Func<Loan, bool>> Expression
    {
        get { return loan => loan.DateReturned == null && loan.DateDue > DateTime.Now; }
    }
}

 

Then, if we can just find some way to modify the query expression before executing it, we could just swap out the IsOverdue method call with the expression defined by its specification, so that the query passed to the ORM becomes this:

var overdueLoans = from loan in dataContext.Repository<Loan>() 
                   where loan.DateReturned == null && loan.DateDue > DateTime.Now 
                   select loan;

 

Modifying Expression Trees

There’s an article on MSDN which details exactly how to do this, and reading Tomas Petricek post about dynamically building linq queries is what gave me the idea to go down this road in the first place. Basically, what we need to do is traverse the expression tree and create a new one based on it (because expression trees are immutable), in which we include the necessary replacements. The MSDN article has the source code for an abstract ExpressionVisitor class that we can use to do this: Its overridable VisitMethodCall method will get called for each method call expression found within the query:

protected override Expression VisitMethodCall(MethodCallExpression m)
{
    object[] attributes = m.Method.GetCustomAttributes(typeof (SpecificationAttribute), true);
 
    // process any method calls decorated with the Specification attribute
    if (attributes.Length > 0)
    {
        SpecificationAttribute specificationAttribute = (SpecificationAttribute) attrs[0];
 
        // create an instance of the specification
        ISpecificationExpression specification = (ISpecificationExpression)Activator.CreateInstance(specificationAttribute.Type);
 
        // and get the expression
        LambdaExpression lambda = (LambdaExpression)specification.Expression;
 
        // we need to replace the argument of the function within the expression with the 
        // reference to the one that is currently in scope
        Dictionary<ParameterExpression, Expression> replaceVars = 
            new Dictionary<ParameterExpression, Expression>{{lambda.Parameters[0], m.Object}};
 
        return new SpecificationExpressionStrategy(replaceVars).Visit(lambda.Body);
    }
 
    return base.VisitMethodCall(m);
}

 

One of the MethodCallExpressions in our query will be the IsOverdue method. However, we don’t really have any way of distinguishing this method call from any other – so I’ve introduced a SpecificationAttribute. When we find any method that is decorated with this attribute, we create a new instance of its associated specification and replace the MethodCallExpression with the one defined by the specification. So for instance, our IsOverdue method would now look like this:

[Specification(typeof(OverdueLoanSpecification))]
public bool IsOverdue()
{
    return new OverdueLoanSpecification().IsSatisfiedBy(this);
}

 

When we execute the following code

var overdueLoans = from loan in dataContext.Repository<Loan>() where loan.IsOverdue() select loan;

 

we can see that the expression tree has been modified, replacing the IsOverdue call with the specification expression

Query for overdue loans

A Bonus: Composite Specifications

Okay, so at this point you might argue that having to go through all these hoops might not be worth it just to regain a fraction of encapsulation, and I’d be inclined to agree, especially when you consider the limitations this implementation imposes (we’ll discuss a few of those in a bit). However, encapsulation is not the only win here. Normally, when implementing the specification pattern, you also end up having to implement support for composite specifications, which can be tricky, and the resulting syntax can be verbose and error-prone. By having hidden the actual specifications totally from the client however, we can now leverage Linq fully and get support for composite specifications implicitly. For instance, we can just write a query such as

var overdueLoans = from loan in dataContext.Repository<Loan>() 
                   where loan.Book.IsOnWaitingList() && loan.IsOverdue() 
                   select loan;

 

and under the covers, the IsOnWaitingList and IsOverdue specifications will be used to inject the appropriate criteria into it transparently. And this is just a simple example; we can use joins, groupings and and all of the advanced Linq features without having to write some complicated specification composition API to support it.

Dangers and Limitations

Unfortunately, there are some issues imposed by the specification pattern implementation I’ve introduced here. First of all, there can be some ambiguity in how the code reads. From the code, it looks as if the IsOverdue method will be called, but in reality it might never be – so if there’s a discrepancy between the specification attribute and the actual implementation of the method, then the code will exhibit different behaviours depending on the call context. Having the appropriate unit tests can safeguard against this, however, so I’m not that concerned about it; but its definitively something to be aware of.

As for limitations; we can only use simple expressions that are convertible to SQL to define a specification in this manner. Specifications that need to access data that is not readily available through the candidate type of the specification will be hard to implement, as will parameterized specifications. I have some ideas on how to solve some these issues, at least partially, so look out for a follow-up post on this soon. Until then, I will hold off posting the source code of the implementation that I’ve been talking about in this post, as I’m not quite confident in sharing it in its current state :)

Currently rated 4.6 by 11 people

  • Currently 4.636364/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Linq to Sql, Programming Against an Interface and the Repository Pattern

An entry about tdd | linq | design patterns | domain-driven design Publication date 5. May 2008 21:56

Program against an interface, not an implementation. I've always been a big fan of that saying. Obviously, in this context interface doesn't necessarily mean an actual interface type; maybe it should have been written as "program against an abstraction, not an implementation" to make that clear. With Linq to Sql - and really most O/R mappers out there that do code-generation - this pretty much goes out the window since you're leaving the O/R mapper in charge of generating the code for the domain model objects for you, based on some (database) schema. What you end up with as a consequence of this, is code like:

var query = from pages in dataContext.Pages where pages.IsPublished select pages;
 
foreach (Page page in query)
{
    // do something with page...
}

 

Here, I'm not programming against an interface - I'm programming against the explicitly implemented Page class. My strongly typed DataContext, autogenerated by the O/R mapper (Linq to Sql), exposes a property Pages which is of type Table<Page>. What I want, though, is an interface IPage that everyone (apart from the factory creating the instance, obviously) should program against; they should never touch the actual Page type.

Partial Rescue

Thankfully C# has got what it takes to solve this, we just have to jump through a few hoops for it. When SqlMetal generated the Page class it made it partial, which allows me to extend the class definition. I can do this by implementing another partial class named the same:

public partial class Page : IPage
{
    IRoute IPage.Route
    {
        get { return this.Route; }
        set { this.Route = (Route)value; }
    }
}

 

At runtime, the compiler will combine both mine and the auto-generated Page class into one. Originally, my Page table had a one-to-one relationship with the Route table. I want the Route property on Page to return an IRoute though, so I've explicitly implemented this property from the IPage interface so that anyone programming against IPage sees an IRoute - but Linq to Sql, which works against the concrete Page type, will of course still see the concrete Route type. The same would be true for any one-to-many relationships; in the interface I would declare them as a generic IList<T>. EntitySet<T>, the type that Linq to Sql uses for collections, actually implements IList<T>, so it's just an implicit cast to get that working too.

But this only gets us halfway there. The autogenerated DataContext still exposes a Table<Page> type, when we really want a Table<IPage> type - or even better, the much more abstract IQueryable<T> type. What we need, is a pattern devised a long time ago...

The Repository Pattern

From Fowler, "conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them". From Evans, "the Repository retrieves the requested object, encapsulating the machinery of database queries and metadata mapping". That last quote is lifted from his book Domain Driven Design (p. 151), which he published back in 2004. What is funny, is that he goes on to say that "a Repository lifts a huge burden from the client, which can now talk to a simple, intention-revealing interface, and ask for what it needs in terms of the model. To support all this requires a lot of complex technical infrastructure". That first part is spot on. But the part about implementing the repository pattern being complex? I guess we've come a long, long way these last four years - C# 3.0 and Linq does away with all the complexity for us, so that all we have to do to implement a super-flexible Repository is defining something like the following interface:

public interface IDataContext, IDisposable
{
    /// <summary>
    /// Gets the repository for the given type of entities
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <returns>The repository of the given type</returns>
    IQueryable<T> Repository<T>() where T : class, IEntity;
 
    /// <summary>
    /// Adds a new entity to the repository
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <param name="item">The entity to add</param>
    void Insert<T>(T item) where T : class, IEntity;
 
    /// <summary>
    /// Deletes the specified entity from the repository
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <param name="item">The entity to delete</param>
    void Delete<T>(T item) where T : class, IEntity;
 
    /// <summary>
    /// Commits the changes to the repository
    /// </summary>
    void Commit();
}

 

That's it! And implementing this interface for Linq to Sql is not much harder:

public class LinqToSqlContext : IDataContext
{
    private readonly DataContext _context;
 
    public static Dictionary<Type, Type> TableMaps = new Dictionary<Type, Type>();
 
    public LinqToSqlContext(DataContext context)
    {
        _context = context;
    }
 
    /// <summary>
    /// Gets the repository for the given type of entities
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <returns>The repository of the given type</returns>
    public IQueryable<T> Repository<T>() where T : class, IEntity
    {
        ITable table = _context.GetTable(TableMaps[typeof(T)]);
        return table.Cast<T>();
    }
 
    /// <summary>
    /// Deletes the specified entity from the repository
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <param name="item">The entity to delete</param>
    public void Delete<T>(T item) where T : class, IEntity
    {
        ITable table = _context.GetTable(TableMaps[typeof(T)]);
        table.DeleteOnSubmit(item);
    }
 
    /// <summary>
    /// Adds a new entity to the repository
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <param name="item">The entity to add</param>
    public void Insert<T>(T item) where T : class, IEntity
    {
        ITable table = _context.GetTable(TableMaps[typeof(T)]);
        table.InsertOnSubmit(item);
    }
 
    /// <summary>
    /// Commits the changes for this unit of work to the repository
    /// </summary>
    public void Commit()
    {
        _context.SubmitChanges();
    }
 
    public void Dispose()
    {
        // we don't assume to manage the lifetime of the data 
        // context, so there's nothing to dispose
    }
}

 

The magic that lets us run queries against for example IPage, is in the Cast<T> extension method in System.Linq. By using it, it allows clients to ask the Repository<T> method for IPage, which then through the mapping configured in the static TableMaps dictionary (where at application startup I've added the mapping between IPage and Page) gets translated into a request for the Page table from the context, and then finally cast back to a IQueryable<IPage> before being returned to the caller, ready for querying against. The implementation-specific code I posted at the beginning of this article can now be thrown away in favour of the following more loosely coupled code:

var query = from pages in dataContext.Repository<IPage>() where pages.IsPublished select pages;
 
foreach (IPage page in query)
{
    // do something with page...
}

 

The Power of an Abstraction is it's Transparent Plugability

One clear win from doing things this way, is the transparent plugability that we achieve by hiding the DataContext behind our repository abstraction. For writing tests, this is invaluable. We can now implement a simple InMemoryDataContext that satisfies all the operations of the interface, allowing us to fake an actual database for testing purposes. The usage of Linq against the IQueryable<T> type means that any query in our application will then instead be executed in-memory instead of translated to SQL, completely transparent from the calling code. My InMemoryDataContext looks like this:

public class InMemoryDataContext : IDataContext
{
    private readonly List<object> _inMemoryDataStore = new List<object>();
 
    public IQueryable<T> Repository<T>() where T : class, IEntity
    {
        var query = from objects in _inMemoryDataStore
                    where typeof (T).IsAssignableFrom(objects.GetType())
                    select objects;
 
        return query.Select(o => (T)o).AsQueryable();
    }
 
    public void Insert<T>(T item) where T : class, IEntity
    {
        _inMemoryDataStore.Add(item);
    }
 
    public void Delete<T>(T item) where T : class, IEntity
    {
        _inMemoryDataStore.Remove(item);
    }
 
    public void Commit()
    {
        InvokeCompleted(EventArgs.Empty);
    }
 
    public event EventHandler Completed;
 
    private void InvokeCompleted(EventArgs e)
    {
        EventHandler completedHandler = Completed;
        if (completedHandler != null) completedHandler(this, e);
    }
}

 

Notice in particular that I've modified the Commit method to raise an event upon being called, so that tests which expect a Commit call can easily assert this. For example, I have a test to verify that when the title of a page is edited, the edited page gets committed to the draft repository (which is another great possibility of having the abstraction at hand - by injecting a special implementation of IDataContext when in page editing mode, I can make it so that changes done in the editor commit to a different storage location than the live data that site visitors see, until the user hits 'Publish'):

[TestClass]
public class When_SetTitle_action_executed
{
    const string route = "#";
    const string newTitle = "##";
    private Page page;
    private InMemoryDataContext context;
    private EditorController controller;
 
    [TestInitialize]
    public void Setup()
    {
        page = new Page {Route = new Route {Path = route}};
        context = new InMemoryDataContext();
        context.Insert(page);
 
        controller = new EditorController(context, MockHelpers.FakeTemplateRepository);
    }
 
    [TestMethod]
    public void New_title_gets_committed()
    {
        bool completed = false;
        context.Completed += (s,e) => completed = true;
 
        controller.SetTitle(route, newTitle);
 
        Assert.IsTrue(completed);
    }
    
// other tests omitted
}

 

And that's it for now. Hopefully this post makes some sense; much of what was written here comes fresh from my Visual Studio instance running in the background. If nothing else, I felt that writing this post helped clarify to myself what I needed to achieve, and that it does in fact seem like a good choice to make for my persistence strategy :)

Currently rated 4.8 by 29 people

  • Currently 4.827586/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.


Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS