Home » .NET Framework » Code Contracts – Invariant

Code Contracts – Invariant

Code contracts are a way to enforce conditions within your code. The last article discussed preconditions and postconditions, which are ways of managing validation on parameters being passed into a method (precondition) and the return values from your method (postcondition).

There is one other primary type of code contract; Invariant. An Invariant contract continuously checks on a class and determines that it is in a correct state whenever work is being performed. To perform this check you will need to create a single method that manages this check. This method can be called anything you want; the contracts subsystem will know what it is for because it has been decorated with the ContractInvariantMethod attribute. In this method you need to manage any business rules that affect the validity of your object. When you have in invariant contract the only time the application can violate these rules is when it is doing work in private methods.

In the following sample, the rule that is to be enforced is that there will never be a time when the Id of the item be less than 0 other than within a private method:

[ContractInvariantMethod]
protected void ManageInvariant()
{
System.Diagnostics.Contract.Invariant(this.Id < 0);
}

The main consideration is when should you use an Invariant? As you can imagine, having a single method responsible for managing the correctness of state for the entire object implies considerable domain knowledge packed into a single place. Thus, it is a potentially key piece of functionality when you are designing your application following the Domain-driven Design (DDD) methodology as DDD strongly recommends that you never work with an object that is in an invalid state. That recommendation is why Invariant contracts were created, to help the .NET framework support DDD.

Does that mean that Invariant contracts should be in every object in your domain? Of course not! Plain-old C# objects (POCO), for example, will rarely need any kind of invariants because they are designed to be a grouping of like data and by definition will not contain any business logic or rules. Domain objects, on the other hand, do contain business logic so are more likely to need invariants.

As you look deeper into the need for invariants you should consider any properties that are set within methods in the class. This consideration should help you determine what properties should be continuously validated. A CreatedDate property, for example, may have a business need for it to never be null. That would be a prime example of a value that should have an invariant check. Other examples could include an EmailAddress or Username for a user object or a Product somehow attached to an order object. Does it make sense to have the primary object if it is missing that piece of information? If it doesn’t, you have a candidate for an invariant.

There is some configuration that you have to do to enable the use of invariant contracts. The image below demonstrates the Code Contracts UI that is added when the Extensions plug-in is loaded:

CodeContractInvariant

You need to ensure that “Perform Runtime Contract Checking” is set to Full else invariant contracts will not be enforced.

This whole discussion has been around the use of code contracts in the .NET framework.  This means that they are also available in the other aspects of the framework including WPF and ASP.NET.  Using code contracts in the models within an ASP.NET MVC is a common usage, as is within the models of an MVVM WPF application.  The framework supports it wherever you will need the ability to ensure a correct and valid object.  Use it where it makes sense.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s