Following on from last month’s blog on Design by Contract, this month we take a look at Microsoft’s implementation of this which is called Code Contracts.
First a little background into why you might want to implement Code Contracts in your .NET projects. Let’s take a simple method which we might have written called Divide which is going to be used for mathematical calculations in our project. The method is going to take two integer parameters, num1 and num2. The method should divide num1 by num2 and return the result as a decimal value.
Here’s a basic implementation of this method which we have created in a Calculator class:
Next, we decide to improve on this by adding in some validation checks for the input parameters.
We will check that we don’t pass a zero as the second parameter (which eliminates any possibility for a DivideByZeroException). Also, for whatever business requirement we have we are going to prevent negative numbers from being passed in.
After adding these in the form of If..Throw statements our method now looks like:
As you can see, this simple method is now becoming harder to read and maintain due to the multiple validation checks. If this were a more complex method with many parameter validation checks to be performed the code would quickly become unmanageable. Invoking the method with an invalid value should throw an ArgumentException:
Code Contracts were introduced in .NET Framework 4.0 and provide a language-agnostic method to express coding assumptions. The contracts are provided by theSystem.Diagnostics.Contracts namespace.
They provide a more efficient means of checking such conditions while still allowing us to implement robust validation methods.
I’ll now go through how to install the Code Contracts components so that they are available in Visual Studio. I’ll then refactor the above method to use Code Contracts.
Installing & Configuring Code Contracts
Firstly, you will need to visit the Visual Studio gallery (http://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970) and download and install the MSI installer for Code Contracts. You should also download and install the editor extensions for VS2010 or VS2012.
When installed, C# and VB projects within Visual Studio are augmented with an extra property pane called “Code Contracts”
The first thing to configure is the Assembly Mode. This defines how you are going to perform argument validation. Assembly Mode should be set to Standard Contract Requires if you use methods Requires and Requires<T> to validate method arguments. You should use Custom Parameter Validation if you use any If-Then-Throw statement as preconditions.
You will also want to tick the Runtime and Static checking modes (more on these later)
Refactoring the method to use Code Contracts
Next, I’ll refactor the previous example to use Code Contracts.
Code Contracts presents us with a number of contract options:
Preconditions – What does the method expect
Postconditions – What does the method promise
Class Invariant – What does the method maintain
In this example I’m taking a look at Preconditions and Postconditions as these are the most commonly used.
Preconditions are implemented using the Contract.Requires method and Postconditions are implemented using the Contract.Ensures method.
Replacing the If..Throw statements with the Code Contracts methods it now becomes:
This code has now become more readable and maintainable.
The Requires methods are invoked before the method code is executed.
This is the generic overload method of Contract.Requires which will throw a specific exception if the precondition boolean condition fails. So in this example if num1 is not greater than or equal to zero an ArgumentException will be thrown by the contract.
Now if we pass an invalid parameter to our Divide method we can see Code Contracts throw the expected exception:
Next, we will introduce a public property to our Calculator class which will hold the last result of the Divide method. We will use a Contract.Ensures method to validate the Postcondition.
This is going to ensure that the Public property value is what we expect it to be after the method has executed its code.
Also, we will add another Postcondition that checks that the value returned from the method is never negative (since our method should only be dealing with positive integer parameters).
Static and Runtime checking
Static checking can be switched on and configured to check for contract failures at design time (i.e. within Visual Studio as you are coding). This can give you an early warning that you have an invalid parameter that breaches a contract before you even encounter that issue at runtime.
For example, if I incorrectly pass a zero as the second parameter to my Divide method Code Contracts highlights the issue and displays an error before I even build the code.
Runtime checking is where Code Contracts will perform checking when your code is executing – This should always be switched on.
Code Contracts begins to really deliver benefits when used in conjunction with Interfaces.
Lest refactor the example above to use an interface.
The ICalculator interface looks like:
Note that I’ve added an attribute to the interface for ContractClass.
This basically binds the interface to use a particular contract class (which I’ll create below).
The concrete implementation of the Calculator class now looks like:
Note that the Contract.Requires methods and one of the Contract.Ensures methods are no longer in the implementation but can be moved in the contract class. One Contract.Ensures method still needs to remain here as it references a public property in this class (LastResult), otherwise it too could have been moved to the contract class.
A new Contract class is created which holds the Code Contract methods.
This also derives from the Interface and is defined as an abstract class.
We now have complete separation between our interface, contracts and implementation.
Unit Testing benefits
The benefits of Code Contracts can also be leveraged when it comes to unit testing.
If we unit test the Divide method in our example it can become very straight forward to check the negative cases such as passing a zero as the second parameter. Our test case should expect an ArgumentException which the Code Contract will throw.
So in summary I believe Code Contracts can provide immediate benefits in your code and are quick to implement with little refactoring of existing code required. You should definitely consider using them if you are employing interfaces in you code as the separation they offer here allows you to structure you solution in a very maintainable and tidy manner.
- Back to Blogs