Design Patterns & Best Practices · Programming

Code: Abstract Unit of Work

Today I’ve been tinkering about how to best implement the
Unit of Work/Repository patterns at the client (service)-side.

Warning! This blog post contains experimental source code!

What I want:
1. Simple to use. Usage is easy to explain.
2. Doesn’t leak the underlying data access framework.
3. Supports transactions.
4. Supports multiple parallel units of work when required.
5. Manages the session/context scope for me.
Not quite sure whether I need nested UoWs.

Here is what I have come up so far. I’ll update this post once I figure out something new about all of this.


// Scoped unit of work:
// 1. Quite simple
// 2. Repositories use the currently active UoW
// 3. Doesn't support multiple UoWs to be active
// 4. Using block scopes the current session/object context
// 5. Repositories are injected using the constructor
using( UnitOfWork.Start() )
{
   var user = this.userRepository.GetUserByName( "Paul" );
   var skill = this.skillRepository.GetSkillByName( "Ruby" );
   user.Award( skill );
}

// Scoped UoW, that also starts a new transaction:
// When the UoW is disposed it will be rolled-back
// unless it has been committed.
using( var uow = UnitOfWork.Start( transaction: true ) )
{
   var user = this.userRepository.GetUserByName( "Paul" );
   var skill = this.skillRepository.GetSkillByName( "Ruby" );
   user.Award( skill );
   uow.Commit();
}

Update:
If the current Unit of Work is marked to be unique for each thread (ThreadStaticAttribute) it can safely handle multiple ‘requests’ at the same time. No need for any >special case< handling.

Thanks to @pragmatrix for pointing this out on Twitter. :)

Advertisements