This time we’ll do a quick exploration of how we can apply Code Contracts to interfaces. As you know from our post First Steps with Code Contracts, the preconditions and postconditions (Contract.Requires and Contract.Ensures calls, respectively) must be placed inside a method body.
Therefore, when defining an interface, we run into a problem: We do not have method bodies there. Of course we could put such calls inside each effective implementation of the interface methods. Clearly, this is not what we want, since
- We do not want to replicate code in x classes that implement our interface and
- Future implementations of our interface would contain the conditions we need
Luckily, the Code Contracts provide us with a powerful mechanism that allows us to define a class which implements that interface and which will do the necessary checks.
The Contract Class
Let’s see how this is done, right? For this example, please recall our example from the First Steps with Code Contracts introductory article.
Snippet 1: The IVehicle interface
Also do recall that we did not define any pre- or postconditions for our interface (how could we? – there is no method body).
This is exactly the place, where we will put a so called Contract Class, that will implement our interface. Every time the interface is called, the conditions put into our Contract Class will be injected. This holds for every implementation of our interface.
We basically need two things:
1. A class that implements our interface IVehicle that is marked as Contract Class via an attribute:
Snippet 2: Contract Class implementing the interface we want to fulfil requirements
2. Another class that links up our interface to the ContractClass
Snippet 3: The link between the interface and our Contract Class
Hint: Don’t worry: You do not have to implement these two classes from scratch: The Code Contracts come with a bunch of predefined snippets that can be executed right away. The following snippet will do the trick for generating the Contract Classes for an interface:
cintf ->(TAB – TAB)
The next step is to implement the interface for IVehicleContract.
Figure 1: Explicitly implementing the interface IVehicle for the IVehicleContract class.
The result is shown in Snippet 4:
As a next step, we can implement our conditions in the method body of IVehicle.Drive method in IVehicleContract, like shown in Snippet 5:
Snippet 5: precondition in interface method implementation.
What does this mean now? Well, for every implementation of the interface IVehicle , the code precondition will be injected. In other words:
The condition we define in the Contract Class must hold for all implementations of the interface.
That was it already (for this time)! It is as simple to use as it seems.
Enjoy and stay tuned for the next time!