Skip to content

Instantly share code, notes, and snippets.

@joshilewis
Created February 5, 2012 14:00
Show Gist options
  • 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>();
dependency.Expect(d => d.SomeMethod("hi"));
var uow = UnitOfWorkTestHelper.GetCommitted();
var sut = new MyClass(dependency, uow.UowProvider);
sut.DoWork();
dependency.VerifyAllExpectations();
uow.VerifyAllExpectations();
}
}
}
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();
}
//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();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary
{
public static class UnitOfWorkHelpers
{
public static void Begin(this IUnitOfWork uow, Action action)
{
uow.Begin();
try
{
action.Invoke();
uow.Commit();
}
catch (Exception)
{
uow.RollBack();
throw;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rhino.Mocks;
namespace ClassLibrary
{
public class UnitOfWorkTestHelper
{
public readonly Func<IUnitOfWork> UowProvider;
public readonly IUnitOfWork Uow;
private UnitOfWorkTestHelper()
{
Uow = MockRepository.GenerateMock<IUnitOfWork>();
UowProvider = MockRepository.GenerateMock<Func<IUnitOfWork>>();
UowProvider.Expect(u => u.Invoke())
.Return(Uow);
}
public void VerifyAllExpectations()
{
Uow.VerifyAllExpectations();
UowProvider.VerifyAllExpectations();
}
public static UnitOfWorkTestHelper GetCommitted()
{
var uow = new UnitOfWorkTestHelper();
uow.Uow.Expect(u => u.Begin());
uow.Uow.Expect(u => u.Commit());
uow.Uow.Expect(u => u.Dispose());
return uow;
}
public static UnitOfWorkTestHelper GetRolledBack()
{
var uow = new UnitOfWorkTestHelper();
uow.Uow.Expect(u => u.Begin());
uow.Uow.Expect(u => u.RollBack());
uow.Uow.Expect(u => u.Dispose());
return uow;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary
{
public static class ValueEqualityHelpers
{
public static bool ValueEquals(this 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;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment