Unit of Work per Action

Most of the time I do any database interaction I follow a "Unit of Work" pattern. This allows good control over when work is submitted to the database, in terms of the Entity Framework, the Unit of Work controls the lifetime of the ObjectContext.

The implementation is pretty simple, we have a UnitOfWork static class that provides easy access to the current UOW as well as starting and disposing. We then have our IUnitOfWork which is where the work of accessing repositories and submitting changes to the database will be done. We then implement that with EntityUnitOfWork.

I like to follow the approach of "Unit of Work per Request" for web applications and usually handle this with an IHttpModule that manages it for me. However for MVC I wanted to try something different. One of the reasons I didn't like Module approach for MVC was that the UnitOfWork was still active during the rendering of the View. This meant that any complex lazy loaded queries could still be evaluated which could leave me vulnerable to N+1 problems.

public class UnitOfWorkAttribute : ActionFilterAttribute

{

    public override void OnActionExecuting(ActionExecutingContext filterContext)

    {

        UnitOfWork.Start();

    }

 

    public override void OnActionExecuted(ActionExecutedContext filterContext)

    {

        if(UnitOfWork.IsStarted)

            UnitOfWork.Dispose();

    }

}

In the end I created a UnitOfWorkAttribute which inherits from ActionFilterAttribute, this enables me to dispose of the current unit of work after the action is completed but before the view is processed. It means that if the view triggers anything that causes database access it throws an error. I can now enforce the convention that all data must be loaded by the action.

[HttpPost, UnitOfWork, ActionName("sign-in")]

public ActionResult SignIn(SignInViewModel details, string returnUrl)

Shout It Kick It submit to reddit

Entity Framework Repositories

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.

Shout It Kick It submit to reddit

Implementing an ActiveRecord pattern in Linq to SQL

In earlier posts I talked about about creating Domain Driven Design style repositories using Linq to SQL. These allowed us to swap between Linq to SQL repositories and In Memory ones easily (and really anything that could support IQueryable<T>, this ensured some very nice testabiliy. In this post I thought I'd go over some it again as well as a some refactoring I had done to simplfy things, as well as how to create simple Active Record style data access on top of our repositories and therefore still ensuring our testability.

Our IUnitOfWork and its implementations (SqlUnitOfWork and InMemoryUnitOfWork) haven't changed. However given that IDataSource<T> and IRepository<T> are essentially the same I decided to remove IDataSource<T>. Now that we have two implentations of IRepository<T> (InMemoryRepository and SqlRepository) we need one that uses these repositories and forms the base class for our aggregate repositories.

This base Repository<T> forms the foundation for it all, internally it's only really a decorator around the actual specialised repository that's accessed from the current Unit Of Work (more about this in a later post).

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

{

    public static IRepository<T> Current

    {

        get

        {

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

        }

    }

 

    public Repository()

    {

 

    }

 

    public IQueryable<T> GetAll()

    {

        return Current;

    }

 

    public virtual void Update(T entity)

    {

        Current.Update(entity);

    }

 

    public virtual void Update(IEnumerable<T> entities)

    {

        Current.Update(entities);

    }

 

    public virtual void Delete(T entity)

    {

        Current.Delete(entity);

    }

 

    public virtual void Delete(IEnumerable<T> entities)

    {

        Current.Delete(entities);

    }

 

    public virtual void Save(T entity)

    {

        Current.Save(entity);

    }

 

    public virtual void Save(IEnumerable<T> entities)

    {

        Current.Save(entities);

    }

 

    public IEnumerator<T> GetEnumerator()

    {

        return Current.GetEnumerator();

    }

 

    IEnumerator IEnumerable.GetEnumerator()

    {

        return GetEnumerator();

    }

 

    Type IQueryable.ElementType

    {

        get { return Current.ElementType; }

    }

 

    Expression IQueryable.Expression

    {

        get { return Current.Expression; }

    }

 

    IQueryProvider IQueryable.Provider

    {

        get { return Current.Provider; }

    }

}

 

Active Record, this seems to be the way a lot of people think data access should be, a few static methods on your classes and away you go. From a testability point of view I feel repositories certainly work better, but for smaller data driven applications Active Record can certainly be the way to go.

I'd like to support both camps with this system so lets build on top of what we already have, first we'll need a static accessor to the current repository, we can do that through the unit of work, but since we already that in our base class we'll just expose that. Now anytime we need our repository it can be accessed through Repositor<T>.Current. This lets us built our ActiveRecordBase.

public abstract class ActiveRecordBase<T> where T : ActiveRecordBase<T>, IIdentifiable

{

    public static IQueryable<T> GetAll()

    {

        return Repository<T>.Current;

    }

 

    public static T GetById(int id)

    {

        return GetAll().Where(i => i.Id == id).FirstOrDefault();

    }

 

    public static IQueryable<T> Find(Expression<Func<T, bool>> predicate)

    {

        return GetAll().Where(predicate);

    }

 

    public static void Save(T entity)

    {

        Repository<T>.Current.Save(entity);

    }

 

    public static void Update(T entity)

    {

        Repository<T>.Current.Update(entity);

    }

 

    public static void Delete(T entity)

    {

        Repository<T>.Current.Delete(entity);

    }

}

 

One important item in there is the IIdentifiable interface, I've seen some posts around either using Dynamic Linq or reflection to implement the GetById method but I prefer this. This won't work for all objects that dont't have an identity column, but for most of mine it's fine. This allows us something really cool, a kinda mix in. A conditional extension method on the repository class.

public interface IIdentifiable

{

    int Id

    {

        get;

    }

}


public static T GetById<T>(this IRepository<T> repository, int id) where T : class, IIdentifiable

{

    if(repository == null)

        throw new ArgumentNullException("repository");

 

    return repository.Where(i => i.Id == id).FirstOrDefault();

}


public partial class Product : ActiveRecordBase<Product>, IIdentifiable

{

    public static IQueryable<Product> GetOnSaleProducts()

    {

        return GetAll().Where(p => p.IsOnSale);

    }

}

 

Next post I'll set up a unit test base class for the in-memory tests and managing our unit of work.

Shout It Kick It submit to reddit

Entity Framework

So there's been a lot of commenting back and forth at the moment concerning the new Microsoft Entity Framework and especially the "vote of no confidence" by members of the Alt.Net and DDD communities. This I can understand, the current EF certainly doesn't meet any of their requirements for a toolset or framework.

The EF team looks to have taken some of this criticism on board and the Entity Framework Design blog gives some good indications we could end up with an excellent toolset.

The bastard step child in all of this is LINQ to SQL, certainly all the attention is on EF and as Ian Cooper says "I would like to see a commitment from the Data Platform team to stop its focus on talking LINQ to SQL down as a RAD tool and tallking up its advantages for use in the OO approaches to software development." I'd like to see this as well. For small to medium projects this could an excellent foundation, I'd love to see it opened up by the Data team, the provider model for it is mostly there, hidden away under internals and sealed classes.

On a personal note, I'm still hunting for a product idea, my brain seems to overly critical at the idea phase. I'm currently working on common libraries for my work and I'll share some of the ideas that come out it soon. I'd like to polish of the LINQ to SQL repositories and building it into a business framework.

Shout It Kick It submit to reddit

Update to DI Container initialization

 Since I wrote the earlier code in "Using LINQ to initialize DI Containers" I've cleaned up the LINQ query to incorporate the assemblies loop and also to use the First extension method to make things a bit more readable.

var services = from a in assemblies

               from t in Assembly.Load(a).GetTypes()

               where t.GetInterfaces().Length > 0 && t.IsSubclassOf(typeof(ServiceBase))

               let i = t.GetInterfaces().First()

               where !Container.Kernel.HasComponent(i)

               select new

               {

                   Interface = i.IsGenericType ? i.GetGenericTypeDefinition() : i,

                   Component = t

               };

 

foreach(var service in services)

{

    Container.AddComponent(service.Interface.FullName, service.Interface, service.Component);

}

 

 

Shout It Kick It submit to reddit