Skip to content

Instantly share code, notes, and snippets.

@joshilewis
Created February 5, 2012 14:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joshilewis/1745709 to your computer and use it in GitHub Desktop.
Save joshilewis/1745709 to your computer and use it in GitHub Desktop.
Simple Unit of Work implementation
using System;
namespace ClassLibrary
{
public interface IDependency
{
void SomeMethod(string s);
}
public class MyClass
{
private readonly IDependency dependency;
private readonly Func<IUnitOfWork> startNewUnitOfWork;
public MyClass(IDependency dependency,
Func<IUnitOfWork> startNewUnitOfWork)
{
this.dependency = dependency;
this.startNewUnitOfWork = startNewUnitOfWork;
}
public void DoWork()
{
using (var uow = startNewUnitOfWork())
{
uow.Begin(dependency.SomeMethod, "hi");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Rhino.Mocks;
namespace ClassLibrary
{
[TestFixture]
public class MyClassTests
{
[Test]
public void TestDoWork()
{
var dependency = MockRepository.GenerateMock<IDependency>();
Action<string> expectedAction = dependency.SomeMethod;
var uow = MockRepository.GenerateMock<IUnitOfWork>();
uow.Expect(u => u.Begin(
Arg<Action<string>>.Matches(actual => DelegatesEqual(actual, expectedAction)),
Arg<string>.Matches(actual => actual == "hi")));
uow.Expect(u => u.Dispose());
var uowProvider = MockRepository.GenerateMock<Func<IUnitOfWork>>();
uowProvider.Expect(u => u.Invoke())
.Return(uow);
var sut = new MyClass(dependency, uowProvider);
sut.DoWork();
uowProvider.VerifyAllExpectations();
uow.VerifyAllExpectations();
}
private bool DelegatesEqual(Delegate expected, Delegate actual)
{
if (expected.Target != actual.Target)
return false;
var firstMethodBody = expected.Method.GetMethodBody().GetILAsByteArray();
var secondMethodBody = actual.Method.GetMethodBody().GetILAsByteArray();
if (firstMethodBody.Length != secondMethodBody.Length)
return false;
for (var i = 0; i < firstMethodBody.Length; i++)
{
if (firstMethodBody[i] != secondMethodBody[i])
return false;
}
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Context;
namespace ClassLibrary
{
public interface IUnitOfWork : IDisposable
{
void Begin();
void Commit();
void RollBack();
void Begin(Action action);
void Begin<T>(Action<T> action, T t);
void Begin<T1, T2>(Action<T1, T2> action, T1 t1, T2 t2);
TResult Begin<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 t1, T2 t2);
}
//Implementation
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory sessionFactory;
private ISession currentSession;
private ITransaction currentTransaction;
public UnitOfWork(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public void Begin()
{
currentSession = sessionFactory.OpenSession();
CurrentSessionContext.Bind(currentSession);
currentTransaction = currentSession.BeginTransaction();
}
public void Commit()
{
currentTransaction.Commit();
CurrentSessionContext.Unbind(sessionFactory);
}
public void RollBack()
{
currentTransaction.Rollback();
CurrentSessionContext.Unbind(sessionFactory);
}
public void Dispose()
{
currentTransaction.Dispose();
currentSession.Dispose();
}
public void Begin(Action action)
{
Begin();
try
{
action.Invoke();
Commit();
}
catch (Exception)
{
RollBack();
throw;
}
}
public void Begin<T>(Action<T> action, T t)
{
Begin();
try
{
action.Invoke(t);
Commit();
}
catch (Exception)
{
RollBack();
throw;
}
}
public void Begin<T1, T2>(Action<T1, T2> action, T1 t1, T2 t2)
{
Begin();
try
{
action.Invoke(t1, t2);
Commit();
}
catch (Exception)
{
RollBack();
throw;
}
}
public TResult Begin<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 t1, T2 t2)
{
TResult returnVal;
Begin();
try
{
returnVal = func.Invoke(t1, t2);
Commit();
}
catch (Exception)
{
RollBack();
throw;
}
return returnVal;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment