Introducing Code Contracts – Exactly what are code contracts and how can they help me in my daily coding tasks? How do code contracts make my code better? Well as I have said before, user input is evil. All user input. Code contracts provide a way for a developer to specifically check what values are coming into their methods and catch issues easily. Here is an introduction to code contracts.
Introducing Code Contracts To Secure Your Code
Code contracts allow you to express coding assumptions in .NET applications. Your first order of business must be to visit the Microsoft Research site. Read the article on code contracts and research it a bit. You then need to download the Code Contracts for .NET installer from the Visual Studio Gallery. After you have installed code contracts, you will find an additional tab called Code Contracts in the project properties.
For this example I just selected to perform Runtine Checking. I also selected Standard Contract Requires. You can also change the Configuration from the dropdown should you wish.
In this code example, assume that we have a class that reads each line in a file. Each line contains the location of a specific log file that we need to process. Then in your method you want to secure with a contract, add a Contract.Requires expression. I am defining the exception (in my case FileNotFoundException) to the condition to check if the file exists. If the file does not exist, the message I defined will be displayed in the exception thrown.
You can also define a code contract to properties. This will then ensure that the path set is a valid path. The private setter also maintains encapsulation in your class. So as soon as you run your code and you somehow pass a path to a class that gets deleted, the contract will catch the missing file.
This is fantastic, and allows developers to tightly control the parameters coming in to your method. You will also notice that I used a Contract.Ensures. This basically tells my calling code that I ensure that this method will return a value greater or equal to 0. But what if we wanted to enforce the use of code contracts and keep our code stable.
A situation could exist where there are more junior developers working on the same project. You need to enforce code contracts as part of your coding standards and also lock down the internal workings of the class by contracting property values. Well, go back to the settings for the project and enable ‘Perform Static Contract Checking’. I enabled ‘Fail build on warnings’ too.
This time, at the top of your class, add a private void Invariants method and decorate it with the [ContractInvariantMethod] attribute. You will see that I have a property called ProcessFileCount that defines the maximum number of log files to process. This is because I don’t want to allow the class to process more than 100 log files at a time. Inside the Invariants method, define a code contract to check the value of our ProcessFileCount property.
In the calling code, instantiate the class and pass the ProcessLogFiles method (that also sets our property) a value of 120. As soon as you build the code you will receive the build errors as seen below. One of the errors specifies that the value passed to our method exceeds the maximum value allowed.
Let us go and correct the error, and pass it a value of 50. Therefore, the class will only process the first 50 log files in the file we passed to it in the constructor.
When we build again, we see that the build fails a second time. This time (as before) it tells us that we have written bad code. We have not added a code contract to our method. Looking at the method, we can see that Visual Studio has underlined the offending line of code and that we do not implement code contracts.
This is easily remedied though by adding a code contract to the method.
From the code above, and by implementing our Invariant method, we can ensure that other developers working on this specific class always add code contracts to their code. It is better to catch these issues during development than to do so during UAT.