Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm getting into the Repository pattern (which I love), and as I read up on it I see this UnitOfWork pattern in many articles. Before I knew anything about UnitOfWork I was just using my Repository pattern inside my service layer (business logic). This seems to work great so I'm wondering why having another layer (ie. UnitOfWork) may be beneficial?

Why would I want a UnitOfWork layer in my service/business logic layer? If your service layer is specific enough and doesn't cover everything under the sun then it doesn't seem like it's needed.

Note that I'm looking at this from an EF perspective. I've even read articles where people mention that EF's DbContext is a UnitOfWork. So why make my own UnitOfWork if EF's DbContext already does this for me? Why not create my DbContext in my service layer and then pull in the repositories I need and do all good?

The Repository I get because it makes testing my services easier, but I don't see the benefit of a UnitOfWork especially if you are using an ORM.

share|improve this question

migrated from codereview.stackexchange.com Apr 11 at 15:48

This question came from our site for peer programmer code reviews.

1  
I'm still mulling this one over, but certainly worth the read. wekeroad.com/2014/03/04/… –  ScottS Apr 12 at 18:14

4 Answers 4

I typically use the UnitOfWork to abstract away the knowledge of database transactions (and subsequently works well as an abstraction layer over my orm). The idea is, repositories are responsible for the logic of accessessing and modifying data, the unit of work handles when those actions get performed. It's a great tool for removing some complexity and redundent database calls from your application.

Basically, the unit of work is part of your repository/data access layer, you inject a unit of work factory or provider into your repositories, who use that to perform their actions. I usually encapsulate this interaction between the unit of work and repository into a base "Repository" class.

There is an incredible amount of power and flexibility that comes from doing this. Your repositories can know less about your application, and become much more streamlined and reusable. Usually through some form of IoC container, you can set the scope of the unit of work (PerRequest) for example. Without changing any code in your repositories, you can now optimize say a web page, to do a single transaction per web request, which in some circumstances can lead to a massive performance boost in the page.

Also, by wrapping say nhibernate session in a unit of work implementation, your repositories become completely unaware of what ORM you are using, and instead focus on providing Linq queries and actions to the rest of the application. With all the transaction management taken out of your repositories, things are much cleaner, and you have a lot more flexibility when it comes to "Tuning". (Reusing your data access layer in a parsing application? Change your unit of work scope to be per file or per 1000 rows, and no code in your repositories change).

All in all, I don't really do repository pattern without a unit of work. They go hand in hand, and both are easier to do with the other one present.

share|improve this answer
    
My repositories don't know anything about my application as it stands right now though. Sure they are using EF created objects, but those are just POCO anyway. –  user441521 Apr 11 at 15:44

Your service layer might look simple now, but if you are building this application for a client they ultimately shape the service layer, not you.

What if the client requires that they can edit multiple items at once, changing any number of item properties, some of which are part of denormalized database tables? What happens when EF throws a concurrency exception during one of these commits?

Things can get real messy real fast. Just because a pattern exists doesn't mean you need to find a place to apply it in your application. One answer to your question is that you might want an additional UoW layer when you need to implement your own change tracking and concurrency handling logic beyond what EF provides as part of the DbContext.

share|improve this answer

From: http://martinfowler.com/eaaCatalog/repository.html

Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

The issue is here:

So why make my own UnitOfWork if EF's DbContext already does this for me?

If you are using a classic repository pattern, the service layer would not know that there is a DbContext, or a db at all, the service layer just knows of a repository, and that calling the repository gets the data from parts unknown and returns it.

if the service layer is unaware of the storage mechanism, how would it perform a transaction? how would it perform transaction-like interactions across different providers (different databases, web services, etc...)? The UnitOfWork pattern is more general than a database transaction and helps to coordinate the Repositories in a transactional manner, spanning databases, potentially even spanning client requests.

share|improve this answer

If you are a 100% sure you won't change your ORM in the future then no need to use UOW, EF does it for you, but if there is a need to change your ORM in the future, (for example if you will need dynamic tables creation, or an ORM that is more performant than EF) if you have a UOW layer that abstracts away your DbContext , you will find it easy to change the ORM.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.