Thursday, January 27, 2011

A Base Class for Entity Framework based Data Access Repositories

While building a personal project which used Entity Framework, I wrote lots of little helpful pieces of code (as you do) to help me do common things.  One of them was a Repository base class that I used to manage object creation and disposal of my DbContext instances.

If we look at the DbContext class definition, we can see that it implements the IDisposable interface:


This signifies that we should dispose of our instances when we have finished using them.

In my application I decided to push both creation of the DbContext instances and their disposal down into a common base Repository class.  I then implemented IDisposable so that my container (Autofac) could effectively handle the lifetime management for me.

In the end, this is what my base Repository class looked like:
public class RepositoryBase : IDisposable
{
    protected readonly VideoLibrary db = null;

    public RepositoryBase(string connectionString)
    {
        Guard.ArgumentNotNullOrEmpty(connectionString, "connectionString");
        this.db = new VideoLibrary(connectionString);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
        

    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
            if (db != null)
            {
                db.Dispose();
            }
        }
    }
}
In the example code shown here, the VideoLibrary is my application's DbContext class.

Sitting above this repository base class are all of my specific Repositories.  Having the db instance managed by the base class keeps my actual repository code clean as I simply reference what I need off of a "live" db instance.  An example can be seen here in a snippet of my TagsRepository:
public class TagsRepository : RepositoryBase, ITagsRepository
{
    public TagsRepository(string connectionString) : base(connectionString) { }

    public Tag GetTag(int tagId)
    {
        return db.Tags.Where(s => s.Id == tagId).FirstOrDefault();
    }
}
The alternative to doing this would have been to configure Autofac to lazily create the DbContext instances outside of the repositories and inject them in, but I opted for this method as I felt that it simplified the overall structure of my code.

No comments:

Post a Comment