views:

398

answers:

6

Should a Controller ever need to call a Repository directly, or should it always run though the service layer? Or are there other options?

A: 

All of the examples I have been working with seem to suggest that the controller should operate on the model.

That said, I've heard some authors suggest that the model is composed of everything from business logic to data repository (as opposed to the business object classes that many consider to be the model).

Personally, I would try to keep it clean/consistent by having the controller operate on classes that operate against the repository - but I don't think there is a hard/fast rule against it.

Mayo
Comment on why you don't like the answer guys... otherwise nobody learns. :)
Mayo
It says +1 not -1? Although it wasnt me who did the vote, the answer doesnt really help. In the Repository/Service pattern there is no model the model is Repository/Service. I'd like to just operate on the service but I'm not sure if this will result in excessive code duplication
Pino
I see... then that might explain the -1. I just assumed you were calling it different terminology - not a different concept. Gives me something to research today (slow day at work).
Mayo
-1 the answer does not help. pointing the asker towards the model is confusing at best. refer to my answer
cottsak
I didnt -1!!! Read my comment.
Pino
Knew it wasn't you Pino :) - it's all good.
Mayo
Your model should not deal with its own repository. You deal with the repository from the controller (or service) and get an instance of the model object from there.
UpTheCreek
+8  A: 

If you have a service layer and your're using it in a way that abstracts the business logic away from the repository (as you should with a service layer) then no, your controllers should only be making calls to the service methods. The service layer will then be the coupling to the repo.

Further to Mayo's answer: the model are the data classes that will be passed throughout the application (repo, service and UI/controllers) so the UI/web layer should 'operate' on them just like the other layers will.

I think if you implement a service layer in the context of Fowler's definition and the modern aspnet mvc adaptions, then you should have your controller actions designed as very small and lightweight methods, calling the 'meaty' business logic from your service layer.

EDIT: I guess i wasn't clear: I'm not saying having a service layer is the only option, just trying to answer part of the question pertaining to the case where you do use a service layer. Agreed, a service layer is not always necessary, especially for smaller projects.

cottsak
+1 for the service layer links
Mayo
A: 

The controller interprets user input and prepares models for use by the View, as I have come to understand it. Some people are real serious about removing every bit of logic from the models, but I'm not that anal about it.

The best option IMHO is to use DI to access your repository from within the controller.

Will
I assume you meen? "every bit of logic from the controller,"
Pino
Um, no, every bit of logic from the models. The models do NOTHING but store data that the CONTROLLER has gathered in response to user input/requests.
Will
That would be an 'anemic model', and not considered very good practice by most people: http://en.wikipedia.org/wiki/Anemic_Domain_Model
UpTheCreek
"The models do NOTHING but store data that the CONTROLLER has gathered in response to user input/requests" First person i've ever heard say that.
Pino
Really? Again, its a question of style how much logic is in the models. Some people don't even do calculations in models. I'm less stringent on that (I will use ORM entities and have my models do calculations) than most people. But the Controller definitely sits atop Models and Views.
Will
@Pino: if you study the approaches from the links i provided you will find those authors tend to agree with Will - the domain model objects are not intelligent (as in they dont really have active methods etc), they are simply strongly typed custom data containers. your collection of domain model objects simply describes how your data is related to itself and provides a lightweight, typed set of containers for passing that data around your application (repo/service/UI/etc)
cottsak
Model objects that can update or 'Save' themselves generally refer to the "Active Record" pattern: http://www.martinfowler.com/eaaCatalog/activeRecord.html Generally the adoption of the Active Record pattern excludes the 'Repository' pattern that we have been talking about here, and vice versa.
cottsak
@cottsak - Sorry, I completely disagree with you regarding this statement "the domain model objects are not intelligent (as in they dont really have active methods etc)". A proper domain model will usually contain methods - a domain model without this is 'anemic'. And: "they are simply strongly typed custom data containers" - you are describing DTOs here not rich domain models. I think you are also confusing the issues by bringing up the save/active record issues. You are implying that repository based models should not contain logic. The Domain isn't just about data, but also behaviour.
UpTheCreek
I agree with Sosh. Fowler's definition of a domain model is "An object model of the domain that incorporates both BEHAVIOUR and data" (http://martinfowler.com/eaaCatalog/domainModel.html). Take a read of Udi's article at http://msdn.microsoft.com/en-us/magazine/ee236415.aspx which highlights how the domain is far more just a set of DTOs.
Luke Bennett
i guess "not intelligent" was not the best way to describe it. i was trying to identify the persisting ability. and maybe i shouldn't have used such a tightly defined term as Domain Model. all i wanted to say was that the 'objects'? that were used in my cited examples were indeed more like the definition of DTO's and did not persist themselves (like Active Records do). whether this is good or bad is subjective, i was just identifying what was in those examples.
cottsak
A: 

The service layer is basically an api for your business logic/business model. For example you might have some method that gets your "best customer". The service layer then does what it needs to do to query the repository, perform whatever logic it needs to do etc, and return the customer. In cases like that you should always go through the service layer.

Sometimes though you're just retrieving an object that might be in your view model, but not in the business model. Certainly you could add a wrapper around the repository in the service layer, but then you run the risk of muddying what your service layer is for and filling it with meaningless stuff. In cases like that I see no harm in going straight the repository.

FinnNk
+7  A: 

You don't always need a service layer - in simple situations it is just over engineering the solution. It's fine for controller to call repository. But, if you see your controllers bloating with logic, or you are repeating yourself in controller actions, then look at putting a service between the controller and repository, and move some of the logic from the controller to ther service layer.

UpTheCreek
+1  A: 

I would agree with @Sosh about the over engineering point. But I have found one great benefit from having the controller go through a service in that when it comes time to reuse that service over the wire via SOAP/REST your refactor work is very minimal. Keep in mind this violates YAGNI and it's thinking ahead (to some extent).

But then again - after reading the latest book by Jeffrey Palermo - MVC In Action, he has a controller with zero logic talk with a repository directly and it works just fine.

Toran Billups
Yeah, good point about web services.
UpTheCreek