4

Possible Duplicate:
How to implement Unit of work in MVC: Responsibility

Hi. I am developing an ASP.NET MVC web application using the following architecture: UI -> Controller -> Service Layer -> Repository. The question here is where to expose the Unit Of Work pattern. For instance I have:

public class SomeController
{
    public ActionResult AnAction()
    {
        using(var unitOfWork = UnitOfWorkManager.Create())
        {
            try
            {
                this.ServiceA.Foo();
                this.ServiceB.Foo();

                unitOfWork.Commit();
            }
            catch(Exception ex)
            {
                unitOfWork.Rollback();
            }         
        }
    }
}

Is it ok for the controller to know about unit of work? What if we have several calls to different services but within the same action method and we need transactional behavior?

1

1 Answer 1

4

We have built an application with the same architecture and our view was that the UOW class is used exclusively in the Services. Reasons:

  1. We think the actions should only have view logic so if possible should not know the business rules associated with using multiple repository calls
  2. Business logic rules should (As much as possible) be in a service. We have a our services use none or many repositories using the UOW class and a short lived context object.

The Action

public ActionResult List()
{
    var things = ThingService.GetAll();            
    return View(things);
}

The Service

public IEnumerable<Thing> GetAll()
{
    using (ObjectContext context = new Container(ConnectionString))
    {
        var work = new UnitOfWork(context);
        return work.Things.GetAll());
    }
}

Hope this helps

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, but how did you handle the case when for instance one user action requires operations on several services, as in my case? According to your response, I assume that ServiceA object would contain a reference to ServiceB object and call method ServiceB.Foo() from ServiceA.Foo(). I think this complicates the architecture.
Markus in most cases our services are designed to encapsulate one transactions logic. So in this case if the Service handled all of the business logic and then needed to send an email (Another Service) it would know about that service (Injected using Dependency Injection). If it is something more complicated then the Command pattern over the Services lets you build up a transaction of services e.g. A flight booking is changed and that affects an associated car booking. But we did this so we could mix and match services, you might not need this flexibility ...
where do you call Commit? based on your example every service should call Commit by itself but in the case of multiple services interact with each other, you may end up with multiple trips to DB, right?
@ebramtharwat I'm facing a similar problem right now when updating multiple items. Should I have a save method on my service that I call once everything is set? Should I have a instance of the UOW outside of my service to call Commit on. Should I have a save method that I pass a object in, method does nothing with the object, just call uow.commit().
@kheit, there is no one valid solution for this problem. IMHO, you should call uow.commit() should be done from the layer that originally started the request which i believe that would be the presentation layer as it would be the most aware layer. the problem with that approach, is that in some cases you would need to save some data before entering another new data. Sorry for my late reply.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.