Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,128 | Comments: 45,550

filter by tags archive

BooDesign By Contract in 20 lines of code

time to read 2 min | 225 words

Now, before Greg hurls a modopt on me, I want to be clear that this isn't the same thing that Spec# is doing. But it is a very cool way to specify constraints that must always be valid when a method exists.

Here is the code:

class EnsureAttribute(AbstractAstAttribute):
	expr as Expression
	def constructor(expr as Expression):
		self.expr = expr
	def Apply(target as Node):
		type as ClassDefinition = target
		for member in type.Members:
			method = member as Method
			continue if method is null
			block = method.Body
			method.Body = [|
						assert $expr

And the usage:

[ensure(name is not null)]
class Customer:
	name as string
	def constructor(name as string):
		self.name = name
	def SetName(newName as string):
		name = newName

Now, any attempt to set the name to null will cause an assertion exception. This technique is quite powerful, and very easy to use. A few years ago I wrote a design by contract implementation for boo that was far more ambitious (handling inheritance, etc). I remember it being much more complicated, and while things like quasi quotation do make it easier, it is not that big a change.

I think that mostly it is the way I write code now, striving to simplicity is something that I am trying to apply recently, and I think it works.

More posts in "Boo" series:

  1. (05 Nov 2009) The Wheel of Time – The Gathering Storm
  2. (11 Aug 2009) Yellow Eyes
  3. (24 Jul 2009) Watch on the Rhine
  4. (23 Jul 2009) By Heresies Distressed
  5. (23 Jul 2008) By Schism Rent Asunder
  6. (04 Oct 2007) Making Money
  7. (30 Sep 2007) Empire of Ivory
  8. (08 Sep 2007) Empire Of Man
  9. (01 Sep 2007) March Upcountry
  10. (21 Feb 2007) Programming WCF Services
  11. (09 Feb 2007) Windows Developer Power Tools
  12. (25 Sep 2006) Old Man's War
  13. (03 Sep 2006) His Majesty's Dragon / Throne of Jade / Black Powder War
  14. (30 Aug 2006) Applying Domain-Driven Design and Patterns
  15. (18 Aug 2006) Dzur
  16. (15 Aug 2006) When Darkness Falls
  17. (22 Apr 2006) Data Binding with Windows Forms 2.0
  18. (17 Oct 2005) Knife Of Dreams
  19. (28 Aug 2005) Working Effectively With Legacy Code
  20. (25 Jul 2005) Harry Potter and the Half-Blood Prince
  21. (14 Jul 2005) Sword of Ice
  22. (14 Jul 2005) Vows & Honor Trilogy
  23. (14 Jul 2005) The Mage Storms Trilogy
  24. (14 Jul 2005) Winds of Change
  25. (10 Jul 2005) Winds of Change
  26. (09 Jul 2005) Winds Of Fate
  27. (08 Jul 2005) Burning Water
  28. (08 Jul 2005) By The Sword
  29. (06 Jun 2005) Developer To Designer
  30. (05 Jun 2005) The Last Herald Mage
  31. (01 Jun 2005) Arrow's Fall
  32. (01 Jun 2005) Arrow's Flight
  33. (27 Apr 2005) Domain Driven Desing
  34. (01 Apr 2005) Exile's Valor
  35. (18 Jan 2005) Alta
  36. (16 Jan 2005) Coding Slave
  37. (13 Jan 2005) Hibernate In Action
  38. (25 Oct 2004) In Search of Stupidity


Bill Barry

wow, that right there is basically what I just said on the alt.net list is a capability I wish would be available for C# 4.0.

How do you come up with this stuff so fast?

Ayende Rahien


Take a look at the code and you'll understand how I come with it so fast. It is simple, when you know how.

Bill Barry

That I realize, I was referring to the "person X thinks about it, you have already made a blog post about it" concept. It is like you are in all of our heads.

(In this case your post came before my comment on the list, I just hadn't seen it yet.)

Tobin Harris

That looks cool! I guess it would be easy to put them on methods too, such as:

[invariant(name is not null)]

class Customer:

[precondition(orders is not empty)], [postcondition(discount is not null)]

def ApplyDiscount():

Ayende Rahien


Yes, you can put this on methods as well.

Joe Gutierrez

How about something like this:

[ensure(name is not null) and (name is not empty)]


concatenations of operators?

Ayende Rahien

This will work:

[ensure(name is not null and name is not empty)]

Joe Gutierrez

Do you have unit tests for the dynamic code?

Robert Taylor

When is EnsureAttribute.Apply(...) called? and by what?

Ayende Rahien

During compilation, by the compiler

Robert Taylor

I'm guessing that Apply is inherited from AbstractAstAttribute and the compiler has a "built-in rule" to call Apply on all AbstractAstAttributes?

Comment preview

Comments have been closed on this topic.


  1. The worker pattern - about one day from now

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    26 May 2016 - The client side
  2. RavenDB 3.5 whirl wind tour (14):
    25 May 2016 - Got anything to declare, ya smuggler?
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats