Service Layer/Repository Pattern

2019-03-21 17:45发布

问题:

I am building an MVC app using the Service Layer/Repository/Unit of Work pattern with EF4.

I am a bit confused on the logic. I know the point is to decouple the system, but I am a little confused.

So the MVC Controllers call on the Services to fill the View Models. So is it safe to say the MVC App is coupled to the Service Layer?

Then the Service Layer calls on the Repository to get and persist objects. Is then safe to say the Service Layer is dependent to the Repository?

The Repository the utilizes EF4 to get and persist data to SQL server, so I would assume the Repository depends on EF4 which in turn depends on SQL Server.

Where does the unit of work all fit in.

Any examples please? Thanks!!

回答1:

I started with hiding Unit of work somewhere in lower layer but it is wrong way to do that. After some experience my opinion is:

  • In case of monolitic application UnitOfWork should be accessible by Controller and lower layers.
  • In case of distributed application (UI and BL are on different servers) UnitOfWork should be accessible by business layer facade (service layer for remote calls) and lower layers.

The reason is that mentioned layers define what is the "business transaction" = what is current unit of work. Only this layer knows when it wants to commit changes to data store. Doing it this way allows service composition (code reuse). I discussed similar question here and here.



回答2:

Sam,

Julie Lerman did a good screencast on DNR tv, talking about this, there is also another screen cast on Channel 9, around creating and testing repositories just EF here.

The general thing abut these is create the abstraction of the Unit of Work in Nhibernate it would be Session, in EF would be you context and passing that session or context into your repositories, as part of you test you can fake the connections to use a list of dictinary.

Hope these help.

Iain



回答3:

You are correct in your assumptions on the layering. Your EF Context is the Unit Of Work. Generally you'll abstract this away through an interface and then constructor inject into each Repository for CRUD operations. Another approach is to expose your Repositories on the UoW interface (I prefer the former). Either way allows for easier unit testing of each layer. A single call to Save on the UnitOfWork from within the service layer will then persist all changes across all Repositories.

Here's a nice article on MSDN that looks at UoW from a unit testing perspective but covers repositories also. Where it references Repositories from the MVC Controller you'll have another intermediary service layer.