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
An argument for moving ASP.NET MVC controllers to a separate assembly

I'd like to buy an argument.

I'm a proponent of isolating application tiers via separate physical assemblies; e.g., MyProject.Core for domain objects and logic vs. MyProject.Web for views. While I do not encounter much push back with this idea, I seem to raise eyebrows with my desire to move ASP.NET MVC controllers to a separate assembly as well. The result of creating separate, physical assemblies for the logical tiers, including the controllers layer, has a number of benefits.

The first and primary reason is that it decreases your ability to shoot yourself in the foot.  Let me tell a war story to illustrate.  About five years ago I was given the privilege to build the most exciting application of my career thus far.  In developing it, we tried to emphasize adding complexity and patterns only while refactoring smells and keeping things as simple as possible (which is almost always the best route to take).  We didn't take many prefactoring steps and let the system evolve organically.  A painfully learned lesson was putting all of the tiers into one physical assembly and separating them only by namespaces and "team agreement."  The major drawback to this was that every layer was technically able to communicate with any other layer, even bi-directionally.  (Yes, the most excellent NDepend could assist, but what happens when you have to leave a project in another developer's and/or team's hands for a while?)  Inevitably, bi-directional dependencies began to creep into the code.  Progressively, the unit tests, for testing the domain layer, started becoming more and more dependent on an up to date test database and working external services; shortcuts began creeping in to the data layer and external services.  Accordingly, the unit tests became slower, more fragile, and tedious to maintain.  This bleeding of one layer into another had a few ill effects:  developers stopped writing and running unit tests (because they were agonizingly slow to run), the application overall became increasingly difficult to maintain and difficult to make modifications without inadvertently affecting various layers simultaneously, and it became almost impossible to upgrade the data layer without touching all of the layers of the application.  Yes, I could have done a lot more to prevent some of these problems, both technically and managerially...but I can't say I've learned as much from any other project as well!  (A computer science professor of mine once said that you're not an expert until you've made every mistake in the book...that project almost gave me my expert credentials in one fell swoop.  Just kidding, I have plenty more mistakes to make. ;)

Some of the other benefits of having physically separated tiers come out of this story as well:

  • It's helpful for being able to unit test logical tiers in isolation,
  • It's simple to upgrade your data access layer if only the IoC mechanism depends on it directly,
  • It's easier to manage a group of developers which can't violate the rules when separated assemblies can only depend on each other in one direction, and
  • It's easier to understand (aka - maintain) a tier's responsibilities which have been physically separated from other tiers.

Moral of the story:  take necessary prefactoring steps to make applications easier to unit test and maintain...and to make it very hard for you to shoot yourself in the foot!

As a working example, due to these reasons, S#arp Architecture projects have a core domain layer which physically cannot have concrete dependencies on the project's data access layer.  Likewise, the controllers layer doesn't have a concrete reference to the data layer or to NHibernate.  In addition to separating concerns, this physical layout of the layers, and the direction of dependencies, acts as a form of implicit documentation to the developers how the layers should be used.  E.g., YourProject.Controllers knows nothing about the implementation details found within YourProject.Data; YourProject.Core has no concrete clue what the persistence mechanism is; and YourProject.Controllers could care less about which IoC mechanism you're using or what static properties Global.asax.cs might be tracking.

Contrastly (is that a word?), moving the controllers layer into the physical web assembly automatically gives it automatic access to all the references that a web project typically has; references such as your IoC implementation, NHibernate and YourProject.Data.  Likewise, mashing any other layers together makes it that much easier for a developer to bleed concerns from one layer into another, inadvertently as it may be.  Certainly, there's a lot to be said for discipline, team agreement, and tools such as NDepend to make sure your team is following the rules, but I feel it's beneficial to go a bit further to make it that much more difficult to make a mess of things.  When considering the wide breadth of skill levels of developers who may ever be touching a project that you're leading, I'd lean towards enforcing a separation of concerns by default, and make it that much harder for developers to void the warranty. ;)

If you'd like to rebut, it's one pound for a five minute argument, but only eight pounds for a course of ten.

Billy McCafferty


Posted 01-09-2009 12:21 PM by Billy McCafferty

[Advertisement]

Comments

Paul wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-09-2009 3:26 PM

I've tried it both ways myself and you're right that without strict discipline unwanted dependencies will creep in. I know that dll's should really only be for units of deployment but I'm kinda inclined to agree with you.

Oh and it's contrastingly btw

sergiopereira wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-09-2009 3:50 PM

Billy, I agree with the benefits of separating in different assemblies. Being the picky nomenclature bastard that I am, I'd just rename that assembly to YourProject.Web.Controllers to make it clear which part of the architecture it belongs.

An argument for moving ASP.NET MVC controllers to a separate … | ozpv.com wrote An argument for moving ASP.NET MVC controllers to a separate … | ozpv.com
on 01-09-2009 3:52 PM

Pingback from  An argument for moving ASP.NET MVC controllers to a separate … | ozpv.com

Billy McCafferty wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-09-2009 4:08 PM

sergio, you picky nomenclature bastard! ;)  that's a great idea!

pete w wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-09-2009 4:11 PM

Even if it was a bad thing to do, (just playing devils advocate) it is infinitely easier to consolidate classes into a single assembly than fanning them out into multiple assemblies.

Maybe the controllers assembly could be re-used as a means for additional interfaces to the domain?

A hardcore Ruby developer and I were playing around with your latest build.

One of his initial reactions made me laugh: "For most projects, this architecture is like killing fleas with an atom bomb!" :)

Billy McCafferty wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-09-2009 4:18 PM

Then he'll like my it's-not-a-one-size-fits-all diatribe at groups.google.com/.../0a81f04440487146 ;)

Billy

Kevin Pang wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-09-2009 4:25 PM

Coming from someone who is developing an application in my spare time using the S#arp Architecture framework, I have to say that separating the controllers out definitely makes it harder to shoot yourself in the foot and make stupid mistakes.  There have been times when I've been writing a controller action and tried to access the Repositories or even NHibernate just to throw something together, but end up having to go the correct route and create interfaces instead.  Without the separation, I'm sure I would have went the lazy route and never ended up fixing it, leading to code degradation.

ASP.NET MVC Archived Blog Posts, Page 1 wrote ASP.NET MVC Archived Blog Posts, Page 1
on 01-09-2009 11:38 PM

Pingback from  ASP.NET MVC Archived Blog Posts, Page 1

Shiju Varghese wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-10-2009 12:02 AM

Billy, Sergio's suggestion is a good one

Dew Drop - January 10, 2009 | Alvin Ashcraft's Morning Dew wrote Dew Drop - January 10, 2009 | Alvin Ashcraft's Morning Dew
on 01-10-2009 4:28 PM

Pingback from  Dew Drop - January 10, 2009 | Alvin Ashcraft's Morning Dew

Arjan`s World wrote Arjan`s World
on 01-11-2009 11:58 AM

Pingback from  Arjan`s World

Billy McCafferty wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-11-2009 7:42 PM

Thanks again for the suggestion Sergio...I've made the appropriate changes to S#arp Architecture.

LA.NET [EN] wrote Putting controllers into different assembly on MVC project
on 01-12-2009 2:19 PM

Billy McCafferty , mentor and leader of the S#arp project , has an interesting post where he justifies

ASP.Net MVC: Moving controllers into a seperate assembly | StevenMcD.net wrote ASP.Net MVC: Moving controllers into a seperate assembly | StevenMcD.net
on 01-12-2009 3:04 PM

Pingback from  ASP.Net MVC: Moving controllers into a seperate assembly | StevenMcD.net

ASPInsiders wrote Putting controllers into different assembly on MVC project
on 01-12-2009 3:09 PM

Billy McCafferty , mentor and leader of the S#arp project , has an interesting post where he justifies

kishore wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-14-2009 1:30 AM

bill,

Enjoy your articles. Nice work.

Regarding the controllers, I strongly agree with the separation for the following reasons:

1. Keeping a web project( any UI project for that matter ) as simple as possible and with minimal code.

2. Also agree that unit-testing becomes a bit simpler.

3. Portability.

  For projects that are separated by modules rather than physical layers:

  for example: Here is a modular based project structure:

  In this case, the ForumsRepository, ForumsController both reside

  in the application.forums assembly.

  This controller in this case can be (relatively) easy to port to another project.

- application.core

- application.forums

- application.posts

  As opposed to a phsycial based project structure:

- application.core

- application.dataaccess

- application.services

  In this modular approach, the components tend to be more cohesive when placed in the same assembly.

Shared Tutorials » Blog Archive » An argument for moving ASP.NET MVC controllers to a separate wrote Shared Tutorials » Blog Archive » An argument for moving ASP.NET MVC controllers to a separate
on 01-15-2009 11:59 PM

Pingback from  Shared Tutorials  » Blog Archive   » An argument for moving ASP.NET MVC controllers to a separate

Andy Gibson wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 01-19-2009 7:48 AM

Also inclined to agree with you here. I have read a great number of posts, articles and blogs on the subject of separating the controllers into another assembly.

I like to keep my solution architecture well defined by using multiple projects to isolate individual components of my systems. I have recently begun using IoC with ASP.NET MVC and keeping things organised like this has definitely helped since as you pointed out, you don't have the bi-directional communication issue (unless you actually go out of your way to implement it).

An additional note on this is that if you are developing an application with multiple interface styles (eg. Website, Web Services and WinForms GUI) then you can reuse you domain model and data storage assemblies and only add assemblies for the bits you need. That is not so easy with just a single assembly I am quite sure.

Good article :)

Sosh wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 08-20-2009 10:24 AM

So, are there any downsides to this approach?

That Guy wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 08-28-2009 2:26 PM

What's a feel swoop?

Billy McCafferty wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 08-28-2009 2:38 PM

It's german.  ;)   (Fixed.)

Billy McCafferty wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 09-07-2009 5:08 PM

@Sosh, added complexity due to adding a separate, physical assembly.

Joe Wilson wrote Review of Sharp Architecture
on 09-14-2009 9:41 PM

Review of Sharp Architecture

Sanjay wrote re: An argument for moving ASP.NET MVC controllers to a separate assembly
on 02-24-2010 1:24 AM

Great post. I was thinking about it from some time and was unsure, now its quite clear. Thanks.

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)