7

Who has the responsability


Who has the responsibility to start and finish the Unit of work in a MVC architecture?

SDReyes
  • 9,798
  • 16
  • 53
  • 92

4 Answers4

10

It's not a responsibility of a controller, it violates SRP. Controller should not even know about UoW at all. In web, one UoW per request to server is usually used. In this case UoW should be disposed at the end of a request and started somewhere after the beginning of a request (ideally start of a UoW should be lazy). The best place to do this is Global.asax (or your HttpApplication class) using Application_EndRequest and Application_BeginRequest handlers.
This can be easily achieved with an IOC framework (my favorite is Windsor), see this question for implementation details.

Community
  • 1
  • 1
zihotki
  • 5,201
  • 22
  • 26
  • @zihotki - in your design, what adds commands to the Unit of Work? – Jeff Sternal Feb 10 '10 at 19:39
  • 1
    @Jeff, all commands/services/repositories in the requests share (and belongs to) the same UoW. If the command/service/repository requires a direct reference to UoW (for example, a Session in NHibernate, or DataContext in EF) it should be injected by IOC. How exactly it should be injected (setter or constructor or by direct call to IOC) depends on your architecture. – zihotki Feb 11 '10 at 09:30
  • 1
    "The best place to do this is Global.asax (or your HttpApplication class) using Application_EndRequest and Application_BeginRequest handlers." or you could get a new httpmodule to hook into these events, and give you a nHibernateSession object per request. I agree explicitly controlling the UoW goes against SRP but ultimately the U is inside the context of the page. Nice answer :) +1 – Mark Dickinson Feb 11 '10 at 09:53
  • How about unit tests ? How would you unit test the unit of work this way ? – Rushino Jan 26 '11 at 13:36
  • @Rushino, I'll test the commands and services and I'll create an UoW for each test in "before test" event and close it in "after test" event. But the exact implementation will depend on the command's or service's implementation – zihotki Mar 01 '11 at 15:46
5

The controller. This gets the context, so you can start and finish the unit of work. For example a nHibernate session per request would need you to know when the request had started and finished, so you need the context to give you the request.

Mark Dickinson
  • 6,573
  • 4
  • 29
  • 41
  • +1 Thanks Mark! Anyway I'm going to wait for more opinions about : ) – SDReyes Feb 10 '10 at 16:29
  • 1
    That's cool, it's hard to tell what you want the answer to be, as there is more than one way of looking at unit of work. Some poeple have it as the whole work for a page rendering, others have transaction scopes which could be handled by other classes. Even for more granular cases, I think it is good to have the controller in charge of the resources which it can eventually give back (dispose or whatever). Maybe you could post more and I can try and give a better answer. Thanks :) – Mark Dickinson Feb 10 '10 at 16:33
  • Thanks for answer Mark : ) Well, in a unit-of-work request oriented. I think you are right. I just believe that there could be something be have not considered. : ) -i.e. I hadn't though in transaction oriented UoW : P- Thanks again – SDReyes Feb 10 '10 at 16:47
  • Update: see Zihotki statement. – SDReyes Feb 10 '10 at 22:47
3

I am a believer in loosely coupled architecture. My controller knows NOTHING about the repository, context or unitofwork. I have created a service layer (not sure that is the right term) that the controller calls. This service then works with the repository (dll) to persist all data.

Spydermary
  • 31
  • 2
2

As zihotki said you would be violating the SRP if you give this responsibility to the controller. This is a data manipulation oriented pattern, and as such should not be a concern for the controller ... that would make it two violations: one for the SRP and anothrt for the SoC principle.

As for who has the responsibility, that's something to be defined by your architecture. The StartRequest/EndRequest suggestion seems solid enough.

JoseMarmolejos
  • 1,760
  • 1
  • 17
  • 34