Derik Whittaker

Syndication

News


Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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,


Posted 10-22-2008 7:03 AM by Derik Whittaker
Filed under: ,

[Advertisement]

Comments

Jak Charlton wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 8:11 AM

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.

Derik Whittaker wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 8:19 AM

@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.

Rob Eisenberg wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 9:08 AM

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.

Chris Sutton wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 11:27 AM

@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

Tim Barcz wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 11:28 AM

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.

Adam Tybor wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 11:44 AM

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.

Chris Sutton wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 11:53 AM

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

Tim Barcz wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 11:56 AM

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.

Robin Clowers wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 12:17 PM

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.

Adam Tybor wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 12:50 PM

@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?

Jak Charlton wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 2:53 PM

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

Jak Charlton wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 2:55 PM

@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.

srdjan wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 5:34 PM

Adam Tybor  said:  

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

golden

Steve wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 8:27 PM

I inject a service object into my controllers

controller -> service (transactional) -> dao layer

works well.

Kyle Baley wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-22-2008 9:44 PM

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.

Ollie Riches wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-23-2008 5:14 AM

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.

Arjan`s World » LINKBLOG for October 23, 2008 wrote Arjan`s World &raquo; LINKBLOG for October 23, 2008
on 10-23-2008 4:07 PM

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

Sergio Pereira wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-26-2008 12:22 AM

@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

Will wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 10-27-2008 11:16 AM

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

Dave Schinkel wrote re: How is interacting with your data repository in your controller 'Different' or 'Better' than doing it in your code behind?
on 11-01-2008 1:12 AM

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.

Ian Cooper [MVP] wrote The Fat Controller
on 12-03-2008 8:26 AM

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

Community Blogs wrote The Fat Controller
on 12-03-2008 1:14 PM

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

The Fat Controller - taccato! trend tracker, cool hunting, new business ideas wrote The Fat Controller - taccato! trend tracker, cool hunting, new business ideas
on 12-04-2008 2:18 AM

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

The Fat Controller - taccato! trend tracker, cool hunting, new business ideas wrote The Fat Controller - taccato! trend tracker, cool hunting, new business ideas
on 12-04-2008 3:06 PM

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

The Fat Controller - taccato! trend tracker, cool hunting, new business ideas wrote The Fat Controller - taccato! trend tracker, cool hunting, new business ideas
on 12-06-2008 11:04 AM

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

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)