Unit of work pattern

Jul 17, 2011 at 6:31 PM

I want to discuss about your implementation of UoW. I have a doubts if it is UoW at all. in UoW, you start it, and you track changes, and when you are sure everything is OK etc, you commit it to DB in one batch, hence a name unit of work.

you have in every service in every method you change something call of 

unitOfWork.Commit();
witch calls
DataContext.Commit();
witch calls
base.SaveChanges(); //base in DbContext

lets imagine that you call two services, and each service changes something, but second failed with something and UoW should be canceled, it is a problem since you pushed already something to your DB.

when I learned about UoW, I thought that, in unitOfWork.Commit() I confirm, that this part of it was OK, and when I know that my UoW is finished, on its end I commit all to DB, if something goes wrong, I can tell UoW, you know, I dont want to commit you, and at the end it will not commit my unit of work to DB.

In web application, we could have UoW per request for example, through request I gather info to construct my batch and when request ends, I can commit to DB.

but UoW could have span of multiple requests in web app, and more then one form in winform app, lets imagine, a form, with tabs, and I can do stuff on my child forms, and when I call parent OK, then I can commit.
 
this kind of implementation related to UoW in EF is not first I encountered on the web, but I've decided to discuss it on your implementation.

when UoW is not working like I said, you could get rid of IUnitOfWork and UnitOfWor altogether, and use DbContext directly in your services, sinse UoW class does nothing.


tell me what do you think?


ref:
http://martinfowler.com/eaaCatalog/unitOfWork.html
http://takacsot.freeblog.hu/Files/martinfowler/unitOfWork.html
Sep 16, 2011 at 7:42 PM
Edited Sep 16, 2011 at 7:43 PM

Ive figured out something.. an unit of work isnt needed with entity framework because the context serve as an unit of work. But some poeple like me still want to put one for testing purpose.

To be clear.. the context will automaticly rollback if something happen. So basically there is no need to have one. But like i said you can have one.. but it will just not do what a real unit of work do. So your right.

 

If you want to apply the real unit of work pattern you should consider NHibernate..

 

From : http://msdn.microsoft.com/en-us/library/bb336792.aspx

"SaveChanges operates within a transaction. SaveChanges will roll back that transaction and throw an exception if any of the dirty ObjectStateEntry objects cannot be persisted. "

Nov 16, 2012 at 5:36 PM

>>But some poeple like me still want to put one for testing purpose.

Just curious, what kind of testing purpose you are referring to? I'm finding more and more people copying this practices ... 

Don't you think it's more like antipattern or code smell, when you putting following code over and over again all over the place?

using (var uow = ... ) {

using (var repo = ...) {

imo it violates DRY, YAGNI, KISS

What do you think?