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
Using DbC to Enforce Convention Over Configuration

I've previously discussed the benefits of the under-appreciated technique Design by Contract.  I've found a(nother) great spot where it's usefulness shines while using MonoRail's SmartDispatcherController.  This convenient controller performs automatic parameter binding between a form and its controller.  For example, suppose you're adding a new Customer to your application via a web form; when you submit the form, it'll automatically collate the field inputs into a Customer instance and pass it as a single object to the method handling the submission.  SmartDispatcherController uses reflection to determine which field values should be bound to which controller-method parameters.  This goes back to the wise (and convenient) idea of coding to convention over configuration.

One drawback to convention over configuration within SmartDispatcherController, and in other convention over configuration scenarios, is that if a parameter is mis-named in a method, then a default value of null (or a primitive's default value) will be passed to it.  The following code demonstrates...

Within my Brail view:

${HtmlHelper.LinkTo( 'Delete Something', 'ManageSomethings', 'Delete', item.Id)}

Within my ManageSomethings SmartDispatcherController:

public void Delete(int somethingId) { Something.Find(somethingId).Delete(); ... }

There's a subtle problem in the above code. An HtmlHelper.LinkTo will pass an object id with a parameter name of "id" but I've told my method to expect a parameter of "somethingId." Since there's a mismatch, somethingId will always be 0.

Don't get me wrong, I understand that this is trivial to fix and will be trivial to discover...the first time.  There are many occasions when you're fiddling with parameters or form inputs and a simple mismatch may be introduced.  If not discovered immediately, subtle bugs such as this can become real headaches to pin down and lead to middle-of-the-night "holy shnikies, my site's acting weird" phone calls.  That's where Design-by-Contract (DbC) comes into play.  (If you haven't been introduced to it, please read my previous post on the subject.)

With a DbC framework, you can enforce this convention over configuration by adding pre-conditions to methods which will be automatically bound.  (In my opinion, every non-private method throughout your code that accepts parameters should be using DbC to protect themselves...but I digress.)  The previous code, now with the DbC pre-condition, looks as follows:

public void Delete(int id) { Check.Require(id > 0, "id must be > 0"); Something.Find(id).Delete(); ... }

You'll notice that DbC helped me to see the errors of my way, prompting me to change "somethingId" to "id," accordingly.  Little checks like this, all over your code, take almost no time to write but can save loads of time banging your head against a wall.  As we continue moving towards more dynamic languages, techniques such as Design-by-Contract become more and more critical for building stable, maintainable applications.

Billy McCafferty


Posted 10-04-2007 4:32 PM by Billy McCafferty

[Advertisement]

Comments

DotNetKicks.com wrote Using Design-by-Contract to Enforce Convention Over Configuration
on 10-04-2007 7:40 PM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

web design » Using DbC to Enforce Convention Over Configuration wrote web design » Using DbC to Enforce Convention Over Configuration
on 10-04-2007 8:57 PM

Pingback from  web design » Using DbC to Enforce Convention Over Configuration

Will wrote re: Using DbC to Enforce Convention Over Configuration
on 10-04-2007 11:23 PM

I am just getting started with MonoRail after reading blogs like this and Ayende's for a long time.  I have already used DbC from when you posted it with your NHibernate best practices article.  Very helpful, indeed.  Thanks.

Johan wrote re: Using DbC to Enforce Convention Over Configuration
on 10-06-2007 5:20 PM

Bill,

What's the added value of Dbc when you're using TDD? Isn't that doing the same thing twice.The contracts are asserts and thus only used at debug time. Pleas enlight me :-)

rod wrote re: Using DbC to Enforce Convention Over Configuration
on 10-08-2007 5:04 AM

In your situation Dbc will work only if "id" parameter will be parseable to int. What about if not ? For example  url like this: localhost/.../Delete

Billy McCafferty wrote re: Using DbC to Enforce Convention Over Configuration
on 10-09-2007 6:36 PM

@Johan,

Good question Johan as I see overlap between the two.  I see TDD as a way of saying "here's some documentation on how to the app works and here's some proof that it's working."  Although similar, I see DbC as saying "here's what I promise to do if you treat me right and if you don't, i'll let you know it."  I often find DbC catching many things that were'nt anticipated with TDD.  Since it takes so little time to add it in, I've found it to be incredibly valuable for the effort.  DbC is also much more than just basic asserts in the fact that you can create sophisticated contracts that aren't possible (or very difficult) to enforce with TDD.  There's some further good discussion on a comparison of the two techniques by Googling "TDD vs. Design by Contract."  The applicability of both may be similar, but I find them both in conjunction to be very powerful.

@rod,

Correct indeed.  You could always at a VisualBasic.Information.IsNumeric, or something like that, into your DbC assertion as well.

Johan wrote re: Using DbC to Enforce Convention Over Configuration
on 10-12-2007 2:28 PM

Bill,

Thanks for the answer. I just foud this on codebetter. codebetter.com/.../unit-test-vs-debug-assert.aspx. What do you think about only doing Dbc on the privates. I peronally think using them also on public's makes the whole call chain stronger because unittest's should only test one small responsebility.

Billy McCafferty wrote re: Using DbC to Enforce Convention Over Configuration
on 10-14-2007 10:06 AM

I personally like having DbC in place, regardless of visibility to show rules of use without having to dig through unit tests.  But what's more important, I believe, is that your team picks a standard rule of thumb, and eveyone sticks to it for consistency in the code.

Ultram. wrote Ultram and tylenol 3 with cod.
on 06-05-2008 9:08 AM

Ultram. Ultram er. Ultram medication. How the medicine ultram i.

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)