ASP.NET MVC - Using UnitOfWork

827 views Asked by At

I'm currently working on a web app which consist of 6 layers:

  • Web (reference to ViewModels and Controllers)
  • ViewModels
  • Controllers
  • Services (reference to Data and Entities)
  • Data (reference to Entities)
  • Entities

What I'm trying to is to implement a "UnitOfWork" pattern, and therefore I have a class thats injected by DI for that job which makes it possible to do .commit() in the actionresult in the controller when I'm done with the database.

Now is my question... Where should this UnitOfWork class be placed? It's at the moment in my Data layer but that requires the Controller layer to reference the Data layer AND the Service layer, which is odd in my opinion... Should I move the UnitOfWork class/interface to the Service layer and use DI?

3

There are 3 answers

11
RPM1984 On BEST ANSWER

Unless you're using the Repository pattern in your Data layer, you're wasting your time.

The point of a UoW is to handle changes across multiple Repository instances, this is done in the following ways:

  1. Unit of Work derives from the actual underlying context (DataContext - L2SQL, ObjectContext/EF)
  2. Repositories take a Unit of Work in their ctor.

The Unit of Work do two things:

  1. Have a Commit() method
  2. Expose the underlying object/entity set to the Repository.

It's a little tricky to get it all setup, but once you do, the flow should be like this:

  1. Controller get's DI'ed a service and a unit of work (both via Interfaces)
  2. Controller calls method on a service ("CustomerServices.AddOrder()")
  3. Service calls method on Repository
  4. Repository calls "Add" method on "Order" object/entity set
  5. Controller commits Unit of Work

Essentially, each layer takes an instance of the "next layer" in their constructor. Everything should be DI'ed and interface-driven. The UoW has not reliance on anything - but the Repository relies on it for persistence to the "internal memory" (ORM), then the UoW "Commit" will push the changes out to the database (basically wraps the "SaveChanges" method).

As the Unit of Work is an infrastructure/persistence/database/transactional concern, it should go into your Data layer. Should only be referenced by Controllers.

0
KallDrexx On

I implemented my IUnitOfWork class to be passed directly into my MVC controllers (injected via Castle Windsor). I then have my controller pass it to any service objects it instantiates.

2
John Geng On

IUnitOfWork should be an interface for data layer. When request come into Controller then call service methods, if you require CRUD there should call UnitOfWork. You may use Session Per Request by call UnitOfWork in Global.asax Request_Start and commit works in Request_End.