Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Derik Whittaker

Thoughts on Software Development, .Net, OOP, Design Patterns and all things cool



How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?

Today I was looking through a sample Asp.Net MVC application and the first thing I noticed is that one of the controllers had 4 repositories injected into the controller (hey, at least they are injected right :) ).  The code then went onto to interact with the various repositories in each of the various controller actions.  In one case a controller chatted with a single repository 5 times.....:(

My question is this.  How is having the controller chat with a repository different than having your code behind do so? 

To me this is just NOT good.  In my opinion the controller should only interact with either services (if you buy into that design pattern) or other business layer objects.  I like the idea that my controller actions are skinny (thanks for that term Chris) and contain very little 'logic'.  My fear with MVC is that controller actions will turn into the click events we have today with WebForms.

Am I off base?  Thoughts... Comments.... Lets Debate this

Till next time,



Comments

Casey Charlton said:

Controller actions are not code behind, or even vaguely equivalent ... it is perfectly justifiable to have data access code in a controller, controller actions are, for example, unit testable (unlike code bhind)

While I would normally put data access code further back, for the vast majority of web applications that are CRUD applications, putting in injected repository in the controller is perfectly reasonable.

That said, in the app I have been working on recently, the code base has been degenerating due to this practice, but that is more to do with the complexity of the data operations

If you cannot see a requirement to separate your data access totally from your web application at some point (i.e. behind a  services facade or on another machine), then pushing your data access calls behind another facade just to avoid putting data access requests in a controller is probably a case of YAGNI

The whole point of the repository pattern is that a repository pretends to be a collection of objects - the fact that it may go to a database is transparent to the object (controller) using it.

# October 22, 2008 8:11 AM

Derik Whittaker said:

@Casey,

I see what you are saying.

However, I just have this gut feeling that if it becomes 'common' practice to litter your controllers with data access calls (event if it is via the repository) then future changes become harder.  

The developer is really doing them selves a disservice by not putting their business logic (exactly what this is in most cases) in a central place.  Because we ALL know that this logic will be put into multiple places over the life of the application.

My thoughts are that any 'real' business logic that lives in the controller is bad.  This is just a bad pattern to follow as MUCH, MUCH pain will occur at some point in the future.

You said as much in your comments 'the code base has been degenerating due to this practice'.  You do try to justify it by saying it is with complex data operations, but I am going to assume that they did not start off as complex operations... they grew to be complex.

# October 22, 2008 8:19 AM

Rob Eisenberg said:

Derik, I think you make an important point.  Thinking back to the first MVC apps my company wrote using Monorail, this was exactly the type of problem we had.  We ended up with an anemic domain model with too much stuff jammed into the controllers; and controllers required lots of dependencies.  Recently, we've solved this problem by not only using services, but using the Command pattern.  All our commands live within our domain model, so it keeps not only core business entities in the right place, but core business actions as well (much as a service would).  This makes controllers very light weight and easy to test.  Not to mention that factoring things this way reduces a number of unnecessary dependencies.

# October 22, 2008 9:08 AM

Chris Sutton said:

@Casey,

I'm not sure what all you mean by "it is perfectly justifiable to have data access code in a controller", but I think that is where people are going to abuse the MVC framework the most.

I think the MVC crowd will likely get across the message to pull business logic and data access out of the views, which is a great first step. But the next logical place to try to put it will be the Controller Actions.

The controller actions are there to handle the request, figure out what needs to be done and then delegate off to other places for data and presentation.

If people end up putting unnecessary data access in the controller actions this will put us in yet another mess similar to putting data access and business logic in the code behinds.

Chris

# October 22, 2008 11:27 AM

Tim Barcz said:

I don't know that repository access in the controller is bad.  Is persistence a business rule?  I think not.  I see repositories existing at different levels of the application.  In the domain you may have a repository for shipping rules, something that will never be exposed at the application level.

For example in our app, we have complex rules about where and what can get shipped in the world.  When an order is created those rules need to be pulled from somewhere (ie a repository).  However this is not at the app level, this is down in the domain.  The order then needs to be persisted, this IS at the controller level.  The order doesn't care about persistence, nor should it.  So the repository for an order is at a different level than the shipping rules.

...end ramble.

# October 22, 2008 11:28 AM

Adam Tybor said:

Its all about SOLID.  Separation of concerns and single responsibility scream loud here.

Remember that MVC is just a UI pattern and not some kind of system architecture.

The model does all the work whether its wrapped around services or something else in your domain.  The controller should only be used to orchestrate messaging your domain and signaling a view to render.

When I first started monorail I had several large controller actions and it became a mess real quick.  It was tough to test because my controllers were doing way too much.  Splitting that logic out into application and domain services allowed me to focus on smaller problems quicker and easier.

I like to keep my controller actions lean like any other method.  5 -10 lines tops, and no that does not mean refactoring to a protected helper method inside the controller.

# October 22, 2008 11:44 AM

Chris Sutton said:

Btw, the term "skinny controller" I just lifted from RailsConf '07 and they probably lifted it from another community. It certainly isn't a hard and fast rule, but I think it serves as a useful guideline.

Chris

# October 22, 2008 11:53 AM

Tim Barcz said:

If I have a service that is called by the controller and this service calls a repository OR I have the controller call the repository, what's the difference, you end up with a service making a single call.

The controller's action IS the service layer for many things.

# October 22, 2008 11:56 AM

Robin Clowers said:

I tend to think that if you have a real domain model, you should probably be using services; however, lots of applications don't need a domain model.  If you are building a forms over data application, then there is almost no business logic (other than some validation, which could be on active record objects).  I have seen applications where each method on a "service" just calls a single repository and returns the result.  In these cases, I am all for cutting out the middle man.

# October 22, 2008 12:17 PM

Adam Tybor said:

@Tim

"The controller's action IS the service layer for many things."

I quote Martin Fowler "The controller's job is to take the user's input and figure out what to do with it."

Notice the language "figure out what to do with it" not "do it".

The controllers are not the service layer nor should be used as the service layer like it is in Derik's example.  The controller just figures out what service to call and what output to render.

Its subtle but important because a controller is just a piece of the UI framework not the application model.

Now in the realm of keeping things simple a controller depending on a single repository and making a single call to that repository does not justify an additional service in my book. But I suspect the controller that takes 5 repositories and makes 5 calls to compose a DTO started out with a single repository.

So maybe like the Page_OnLoad and Button_OnClick methods its just knowing when and how to refactor to something better?

# October 22, 2008 12:50 PM

Casey Charlton said:

I would venture to bet that 90%+ of controller actions in 90% of applications require a very simple interaction with at most 1 repository.

So the choice is whether from your controller you do:

itemRepository.GetAllItemsUpdatedThisWeek()

or you do:

itemService.GetAllItemsUpdatedThisWeek() - which then proceeds to make the call above.

However, like all things software, this is a judegement call you need to make on a case by case basis - but separation for the sake of it is silly ... if the controller knows it must call "a thing" to get the latest items to display, whether that "thing" is a repository implementation or a service class that wraps a repository is pretty irrelevant, hallelujah for IoC and ISP - all it needs to do is implement IFetchItems ... problem resolved

# October 22, 2008 2:53 PM

Casey Charlton said:

@Adam >>So maybe like the Page_OnLoad and Button_OnClick methods its just knowing when and how to refactor to something better?<<<

With webforms it was always time to refactor the code out of the handler, you couldn't test anything in the handler - with MVC it isn't so important - testability is a primary reason for separation here - in fact testability is often one of the primary reasons for going MVC over other patterns anyway.

# October 22, 2008 2:55 PM

srdjan said:

Adam Tybor  said:  

"Remember that MVC is just a UI pattern and not some kind of system architecture."

golden

# October 22, 2008 5:34 PM

Steve said:

I inject a service object into my controllers

controller -> service (transactional) -> dao layer

works well.

# October 22, 2008 8:27 PM

Kyle Baley said:

My own personal reason for not injecting repositories into a controller is because I often don't want to expose my domain objects directly to the UI. A lot of times, I want a screen-specific DTO. Cry overkill or YAGNI if you like, it's saved me in the past.

# October 22, 2008 9:44 PM

Ollie Riches said:

I think Derek is right, as MVCs are taken up by more of the community the controller will indeed become the new 'code behind'...

Most developers still don't know what 'business logic' is or how to seperate out responiblity. SOLID most of them they are not.

# October 23, 2008 5:14 AM

Arjan`s World » LINKBLOG for October 23, 2008 said:

Pingback from  Arjan`s World    &raquo; LINKBLOG for October 23, 2008

# October 23, 2008 4:07 PM

Sergio Pereira said:

@Chris,

The "skinny" term comes from an epic post by Jamis Buck. The complete expression was "skinny controller, fat model". It's a great read and a classic for MVC platforms now.

weblog.jamisbuck.org/.../skinny-controller-fat-model

# October 26, 2008 12:22 AM

Will said:

Because you don't do that in your controller; that is done in your models.

# October 27, 2008 11:16 AM

Dave Schinkel said:

Your business logic goes into it's own assembly...you can still have a Business Layer outside of just Controller classes

Your controllers manage calls to your business logic methods which intern call DL methods

Controllers are not your business layer.  So that makes sense to abstract out a controller to facilitate what the code-behind used to do...it's just another abstraction above your business layer and below your presentation layer.  It's not bad to have logic to control what is sent to the views....that's what they are for.

So..I don't see the argument that controllers are bad.

# November 1, 2008 1:12 AM

Ian Cooper [MVP] said:

My latest project is built using the Castle Project stack ( Monorail , Windsor , and Active Record )

# December 3, 2008 8:26 AM

Community Blogs said:

My latest project is built using the Castle Project stack ( Monorail , Windsor , and Active Record )

# December 3, 2008 1:14 PM

The Fat Controller - taccato! trend tracker, cool hunting, new business ideas said:

Pingback from  The Fat Controller - taccato! trend tracker, cool hunting, new business ideas

# December 4, 2008 2:18 AM

The Fat Controller - taccato! trend tracker, cool hunting, new business ideas said:

Pingback from  The Fat Controller - taccato! trend tracker, cool hunting, new business ideas

# December 4, 2008 3:06 PM

The Fat Controller - taccato! trend tracker, cool hunting, new business ideas said:

Pingback from  The Fat Controller - taccato! trend tracker, cool hunting, new business ideas

# December 6, 2008 11:04 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Derik Whittaker

Derik is a .Net Developer/Architect specializing in WinForms working out the northern suburbs of Chicago. He is also believer and advocate for Agile development including SCRUM, TDD, CI, etc.

When Derik is not writing code he can be found spending time with his wife and young son, climbing on his bouldering wall, watching sports (mostly baseball), and generally vegging out. Check out Devlicio.us!

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News