Data access is a popular subject among developers. No doubt you’ve heard plenty of opinions on specific data access technologies and persistence frameworks. Here i have explained Unit of work pattern and how to use it in .net application and advantages.
The Unit of Work Pattern
One of the most common design patterns in enterprise software development is the Unit of Work. According to Martin Fowler, the Unit of Work pattern “maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.”
If you were to build your own Unit of Work implementation, it would probably look something like this interface:
public interface IUnitOfWork { void MarkDirty(object entity); void MarkNew(object entity); void MarkDeleted(object entity); void Commit(); void Rollback(); }
- Manage transactions.
- Order the database inserts, deletes, and updates.
- Prevent duplicate updates. Inside a single usage of a Unit of Work object, different parts of the code may mark the same Invoice object as changed, but the Unit of Work class will only issue a single UPDATE command to the database.
Implementing Unit of Work Pattern using ObjectContext
You can implement Unit of work pattern functionality on NorthwindContext (our typed ObjectContext) without much efforts. The idea is that I can use the Unit of Work to group a set of related operations – the Unit of Work keeps track of the changes that I am interested in until I am ready to save them to the database. Eventually, when I am ready to save, I can do that.
I can define an interface like this to define a “Unit of Work”:
public interface IUnitOfWork{ void Save();}
As explained earlier If you are working on ado.net you can implement Undo(Rollback) functionality as well. As i explained Entityframwork supports the Unit of Work pattern for most parts. I can change my NorthwindContext class to implement the IUnitOfWork interface:
public class NorthwindContext : ObjectContext, IUnitOfWork{ public void Save() { SaveChanges(); } . . .
Now i’m using repository pattern which i have explained in my previous post check here. I’m using the CustomerRepository to demonstration which i have implemented my previous post.
public class CustomerRepository : IRepository, IDisposable { #region Members private NorthwindContext _context; #endregion #region Ctor public CustomerRepository(IUnitOfWork unitOfWork) { _if (unitOfWork == null) throw new ArgumentNullException("unitOfWork"); _context = unitOfWork as NorthwindContext; } #endregion #region IRepository Members public Customer GetById(int id) { return _context.Customers. Where(d => d.CustomerID == id). FirstOrDefault(); } public Customer[] GetAll() { return _context.Customers.ToArray(); } public IQueryable Query(Expression<func<customer, bool="">> filter) { return _context.Customers.Where(filter); } #endregion #region IDisposable Members public void Dispose() { if (_context != null) { _context.Dispose(); } GC.SuppressFinalize(this); } #endregion }
That’s it – we now have our IUnitOfWork friendly repository, and you can use the IUnitOfWork based context to even coordinate work across multiple repositories.
Here’s an example of adding an order to the database that requires the work of multiple repositories for querying data, and ultimately saving rows back to the database(Assuming AddCustomer method exists in CustomerRepository class):
IUnitOfWork unitOfWork = new NorthwindContext(); CustomerRepository customerRepository = new CustomerRepository(unitOfWork); Customer customer = new Customer() customer.ContactName="Test Customer"; . . CustomerRepository.AddCustomer(customer); unitOfWork.Save();
What’s quite interesting to see is how little code we had to add customer to enable data access using Repository and Unit of Work patterns on top of Entity Framework. Entity Framework’s LINQ support and out of the box Unit of Work functionality makes it trivial to build repositories on top of Entity Framework.
Advantage of Unit of Work pattern are,
- Expendable support any data stores and you can easily change above implementation from entityframework to Webservice call.
- Enables and simplifies TDD – Repository pattern and Unit of work pattern simplifies the usage of Mock/Fake object so you can easily test in-memory objects instead of updating the database object.
- Expandable by any data source supporting Linq
- Enhances missing functionalities to EF and Linq2Sql
References:
http://msdn.microsoft.com/en-us/magazine/dd882510.aspx
http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx
http://www.asp.net/entity-framework/tutorials/the-repository-and-unit-of-work-patterns
Similar Topics:
- Repository Pattern in .net
- Implementing Abstract Factory Pattern in .net
- Implementing Factory Pattern in .net
- Dependency Injection (DI) Pattern in asp.net
- Introduction To Model-View-ViewModel (MVVM) Pattern
- Test Driven Development guide
How easy is this pattern to use with TDD? I am currently learning MVC3 and I would like to push this pattern with TDD, but I have not seen anyone really step through the process for this approach…
Anyone?
You can easily integrate Unit of work pattern in your TDD and MVC3 architecture. First frame UOW as explained above and consuming it in your TDD application.