views:

203

answers:

1

Hello

Quick Q for you pattern experts out there.

I want a Repository pattern that is de-coupled from the actual data access tech, as I've not decided on that yet and I want it to be flexible. So, this could be L2S, L2E, NHibernate, Lightspeed or anything.

But I'm getting confused about this UnitOfWork thing.

In the L2S world, this seems to be your DataContext.

But what about a non-L2S world, imagine I was using hand-written SQL for example.

My question is who does what? In my Repo.Save() method, should this call the UnitOfWork.Commit which then generates the required INSERT/UPDATE SQL ?

Not expecting a definite answer, but some discussion would be good, just to make sure I'm on the right track!

Thanks

+1  A: 

Repositories certainly can call commit/save/submit on the unit of work object, or they could leave this up to the consumer. I prefer the latter scenario, because it enables the consumer to control the lifetime of the unit of work instance, which allows the consumer to engage multiple repositories:

// outside the repository layer
// int productId defined elsewhere
// int quantity defined elsewhere

IUnitOfWork unitOfWork = ... instantiate/get a new instance of your DataContext ...

ProductRepository productRepository = new ProductRepository(unitOfWork);
Product product = productRepository.GetById(productId);

Order order = new Order();
order.AddOrderLine(product, quantity);

OrderRepository orderRepository = new OrderRepository(unitOfWork);
orderRepository.Add(order);

unitOfWork.Save(); // This calls SubmitChanges() on the DataContext
mvr
few things wrong with this approach. 1)The persistence technology has leaked into the domain by using the DataContext(L2S). 2) The DataContext can be used outside the context of the repository, clients can simply use the DataContext to generate their own queries, so there is no need for a repository.
An IoC container can solve both of those problems. IUnitOfWork just needs a SubmitChanges method, which means clients that use it would not have access to the data context. You can implement IUnitOfWork in a DataContext partial class. Then for the repositories, they should instead be resolved from the IoC container through interfaces. The concrete implementations of those repositories can have the concrete DataContext class injected via their constructors.
mvr