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:
There is the guard, he will guard this method with a
ArgumentNullException against the instance
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.
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
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.
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.
ExceptionUtil class is just a class to allow throwing exceptions from one place.
The method that gets called looks like this:
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
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
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…
When for example, you add the following code:
It will throw the following exception when the garbage collection starts, to show you how dumb you are. ;)
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.