I’ve been using repositories for data access for some time now but have never successfully implemented anything resembling the Unit of Work pattern. I’ve started a new project for self-education using RavenDB and ASP.NET MVC (details that should be trivial, in theory) and am looking to establish a good way to wrap business transactions (not web requests) in their own units of work, but am having some difficulty doing so.
The following code snippet is what I’d like to see:
public class UserService : IUserService
{
private readonly IRepository<User> _userRepository;
private readonly IRepository<Role> _roleRepository;
public UserService(
IRepository<User> userRepository,
IRepository<Role> roleRepository)
{
_userRepository = userRepository;
_roleRepository = roleRepository;
}
public void Register(User user)
{
using (var session = UnitOfWork.Begin())
{
_userRepository.Create(user);
_roleRepository.AddToRole(user, Role.Public);
session.Commit();
}
}
}
My first stab at a unit of work interface looks something like this:
public interface IUnitOfWork : IDisposable
{
void Commit();
}
public class UnitOfWork : IUnitOfWork
{
private readonly IDocumentSession _session;
public UnitOfWork(IDocumentStore documentStore)
{
_session = documentStore.OpenSession("http://from:config");
}
public void Commit()
{
_session.SaveChanges();
}
public static IUnitOfWork Begin()
{
return IoC.GetInstance<IUnitOfWork>();
}
public void Dispose()
{
_session.Dispose();
}
}
Where I’m stuck is the repositories’ access to the database session. As I mentioned, I’d like to wrap business transactions in their own units; I’m also not keen on passing the session / context into each method, and most other solutions I’ve seen use static methods and / or storage in something like the web session. All of these make me a little uncomfortable; is there something key that I’m missing to this whole Unit of Work concept?
I’m not fond of the
TransactionScopeconcept, and further research & discussion has led me to believe that what I am trying to do is simply not feasible.In the end, the repositories within the
UnitOfWork‘s context need to (explicitly) know about theUnitOfWork. I haven’t settled on which way to go just yet, but I’m going to do something like one of the following:or
I’m not crazy about either approach; I’ll mark this as the answer until I receive a better suggestion.