Should there be a Service Layer in Asp.net MVC between Controller and Repository? As Repository is there for only Data Access. Some business logic is leaked into Controller. This might create a problem if the same operation is used by classic Asp.Net client as we have to duplicate the logic in Controller.
I like the extra level of abstraction a service layer provides between my controllers and repositories. I feel it helps tremendously in fulfilling the Single Responsibility Principle.
I like to have repositories directly in the controller in most cases, and make a service where I feel it leaks. I try to have rich domain objects, but in those cases where logic doesn't fit in the domain classes, I create a service.
I experimented with this a little bit. The app I was building was pretty CRUD-y, and my service layer ended up exposing nearly the same interfaces as my repositories. In addition, most of the service calls didn't add any extra logic on top of the repo, they were just pass-through methods. The only place where the service layer did anything was during an update or insert of a new record. I decided that in a CRUD-based system, the service layer caused more friction than it added value. I ended up extending my business model classes so that the service logic was exposed as operations against the model, thus keeping my controller methods lean and clean.
In a more behavior-driven system, however, I think a service layer might add more value.
I highly recommend using a service layer so you can share common functionality between different web applications. It maybe a case that the architecture is already in existence and you may want to add a new mvc website on the front end.
For simple architectures built from scratch it maybe overkill.
TBH, I've gone both ways on this. My current perspective is that a Repository is a service, it's just a service which happens to have the job of handling CRUD ops for a domain aggregate root. now, if you're "repositories" are directly mapped 1:1 with your entities (and therefore, not repositories so much as DAOs') then I could see the argument. But generally, I add layers of abstraction as needed, but not until proven that they're needed for a given app. Otherwise, you over-engineer.
If you follow Domain Driven Design to the letter, you'll find that there are 3 types of service (don't you love overloaded terms?).
- Domain Services : Encapsulates business logic that doesn't naturally fit within a domain object, and are NOT typical CRUD operations - those would belong to a Repository.
- Application Services : Used by external consumers to talk to your system (think Web Services). If consumers need access to CRUD operations, they would be exposed here (but handled by the appropriate Repository)
- Infrastructure Services : Used to abstract technical concerns (e.g. MSMQ, email provider, etc)
Sounds like you need Domain Services to encapsulate/share your business logic.
Hope that helps!