Click here to Skip to main content
15,885,278 members
Articles / All Topics

A Fluent Syntax Guard Method to Perform (Pre Condition) Contracts

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
9 Jan 2011Ms-PL7 min read 9.6K   2
A Fluent Syntax Guard Method to perform (Pre Condition) Contracts

When you accept the fact that all software contains bugs, then you are able to look at ways to minimize bugs. One of those ways is defining contracts for methods. In this blog post, I will look at creating pre condition contracts for methods.

With the release of .NET 4, the Contract class was introduced in the namespace System.Diagnostics.Contracts, which allows you to, for example write Contract.Requires(object != null) to implement a pre condition method contracts; This is one way of defining contracts, which currently also integrates very well with tools like Microsoft Pex. Before the contract class, there were a lot of different ways in which people would implement pre condition contracts. In this blog post, I will show you another (different) way, which is more fluent and is easier to read. (One downside is that it might be less compatible with Microsoft Pex at the moment.)

To understand the syntax and the concept of pre condition contracts that we are going to build in this blog post, it's essential to understand the story below:

Once upon a time, there was a very friendly and proud guard standing in front of the castle, he was guarding the castle door with his weapon of choice. Friendly and polite as he was, he pointed his weapon of choice towards anyone that didn’t fit the rules defined by the king and would say “I am sorry, but you are unable to enter the castle, because..”.

The guard in the story above will not let any ill people pass, because the king doesn’t want any disease between his safe castle walls. The king instructs the guard to get his illness sword out and tell them to walk away, because the king doesn’t want ill people inside his walls. This way, he keeps the diseases out and everyone is safe.

When looking at the pre condition method contracts, you are that king. You decide what the rules(conditions) are to enter and which sword (Exception) the Guard should throw at any person (object) that doesn’t fit the condition required. Your castle; is the current method to enter.

Now it might be fun to read a programming concept converted to a middle age history story, but it's important to understand this part deeply. If you don’t define the rules correctly, than the guard will not do its job correctly. If the king didn’t make a rule to keep thieves out, then the guard would just let them in. I hope this makes it clear that you are responsible for thinking good and deep about the rules that are required to keep the disease outside of your method. If you don’t trust the people the guard lets in, then make sure the guard doesn’t let them in (the next time).

When using pre and post condition contracts, you are able to define the requirements of the method and describe in some way what it should do. When looking only at the ill people, the guard would take care of the incoming people by a given set of rules, the doctor would take care of making sure the people would leave the castle walls healthy by a checkup (checklist). As long as the guard didn’t have more rules to allow or disallow people and the doctor would not let people out less healthy then his checklist defines, then this process could continue forever. A salesman could move from castle to castle and back to sell his goods. So when you require no more rules, and promise to return no less, then the requirements of the method will stay the same. This is important to realize because it will determine the stability of your method.

Enough explaining, let’s build the guard class. The syntax will look like the following code snippet:

image

There is the guard, he will guard this method with a ArgumentNullException against the instance country being null, and he will say “The parameter country cannot be null”; You will always only use the Guard method calls at the beginning of a method, not in the middle of it. Because the guard is guarding in front of the castle, not from his house inside the secure walls.

To be able to use this syntax, we need to define a class called Guard, with an Inner class called With<>, this class contains the method Against. If the condition given is false, then the guard will let you in and return null. In the else statement, it will return an instance of the Guard object (covered later on), this allows the Extension method Say to be called after the method Against is called.

image

The Say extension method will just look to see if the guard is null (it already lets the person in, the guard doesn’t need to say anything), and throws the exception to say something.

One of the biggest problems with this usage is that the last method in the chain throws the exception, while the Against method already contains the rule. You might forget to let the guard actually say something, and then no Exception is thrown, while you assume it is. To me, it’s just a general rule to always say why you don’t allow this user to enter, because our guard is nice and friendly. To handle this case where you forget to let the guard say something, we will throw a GuardException. This is a little hard to do, since the guard method doesn’t know if a say method is called, after it’s done walking the code inside the method!

I’ve solved this with a solution that is not 100% perfect, but I think it will hit you in the face in most cases (if you forget to add the Say method call). First let’s continue a bit, on the Guard method, the else statement:

image

I retrieve some StrackTrace information to determine where in the code, the method Against is called, this is used later on. I return an instance of the Guard class and set the type of exception to throw.

The Say method will always throw the Exception, because we are now at the point where the Guard has his sword in his hand and is about to make his statement.

image

The ExceptionUtil class is just a class to allow throwing exceptions from one place.

The method that gets called looks like this:

image

We’ve now got everything working, let’s get back to handling the case where you forget to add the Say method. As can be seen in the code samples above, the say method sets the Boolean Handled to true on the Guard instance. This instance is only created when calling the Against method and the condition is true, when it’s false it will just return null. So if you forget to add the Say method, the Handled property will stay false.

We already know that we can’t look forward in time, to find which extension methods it might call. And I don’t want to set a timer object on the Guard object to determine if the Say method (or some event) is called, but what I can do is make use of the destructor of the object, which gets called when the garbage collector runs. So as soon as the instance gets destroyed, it will check if the handled boolean is true, if this object had a call from the extension method Say. I agree that this is an event that you can’t really control, but it’s just to protect you from using it wrong, so I am ok with that. I’ve didn’t see it go bad yet…

image

When for example, you add the following code:

image

It will throw the following exception when the garbage collection starts, to show you how dumb you are. ;)

image

And that’s the end of it. I hope you’ve enjoyed this post and it was understandable, you can get the full code over here.

I will probably later on blog about a method to perform the post condition method contract.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralAbout stack traces and release builds Pin
Pete O'Hanlon9-Jan-11 9:21
mvePete O'Hanlon9-Jan-11 9:21 
GeneralRe: About stack traces and release builds [modified] Pin
erik_nl9-Jan-11 10:31
erik_nl9-Jan-11 10:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.