June 2011

Volume 26 Number 06

Cutting Edge - Invariants and Inheritance in Code Contracts

By Dino Esposito | June 2011

Dino EspositoIn past installments of this column I discussed two of the most common types of software contracts—preconditions and postconditions—and analyzed their syntax and semantics from the perspective of the Code Contracts API in the Microsoft .NET Framework 4. This month, I’ll first introduce the third most important type of contract—the invariant—and then proceed to examine the behavior of contract-based classes when you apply inheritance.

Invariants

In general terms, an invariant is a condition that always holds true in a given context. Applied to object-oriented software, an invariant indicates a condition that always evaluates to true on each instance of a class. The invariant is a formidable tool that promptly informs you whenever the state of any instance of a given class becomes invalid. Put another way, an invariant contract formally defines the conditions under which an instance of a class is reckoned to be in a good state. As emphatic as it may sound, this is just the first concept you need to understand initially, and then implement, when you model a business domain through classes. Domain-driven design (DDD) is now the proven methodology to model complex business scenarios, and it assigns invariant logic a prominent position in the design. DDD, in fact, strongly recommends you should never deal with instances of classes that are in an invalid state. Likewise, DDD recommends that you write factories of your classes that return objects in a valid state and also that your objects return in a valid state after each operation.

DDD is a methodology and leaves actual implementation of the contracts up to you. In the .NET Framework 4, Code Contracts greatly help to realize a successful implementation, with minimal effort of your own. Let’s learn more about invariants in the .NET Framework 4.

Where’s the Invariant Logic?

Are invariants somehow related to good object modeling and software design? Deep understanding of the domain is essential. A deep understanding of the domain guides you naturally to finding your invariants. And some classes just don’t need invariants. Lack of invariants is not an alarming symptom, per se. A class that has no constraints on what it’s expected to hold and what it’s expected to do simply has no invariant conditions. If this is what results from your analysis, then it’s more than OK.

Imagine a class that represents news to be published. The class will likely have a title, an abstract and a publication date. Where are invariants here? Well, it depends on the business domain. Is date of publication required? If yes, you should ensure that the news always holds a valid date and the definition of what is a “valid date” also comes from the context. If the date is optional, then you can save an invariant and ensure that the content of the property is validated before use in the context in which it’s being used. The same can be said for the title and abstract. Does it make sense to have news with neither title nor content? If it makes sense in the business scenario you’re considering, you have a class with no invariants. Otherwise, be ready to add checks against nullness of title and content.

More generally, a class with no behavior and acting as a container of loosely related data may likely be lacking invariants. If in doubt, I suggest you ask the question, “Can I store any value here?” for each property of the class, whether it’s public, protected or private if set through methods. This should help to concretely understand whether you’re missing important points of the model.

Like many other aspects of design, finding invariants is more fruitful if done early in the design process. Adding an invariant late in the development process is always possible, but it will cost you more in terms of refactoring. If you do that, be careful and cautious with regression.

Invariants in Code Contracts

In the .NET Framework 4, an invariant contract for a class is the collection of the conditions that should always hold true for any instance of the class. When you add contracts to a class, the preconditions are for finding bugs in the caller of the class, whereas postconditions and invariants are about finding bugs in your class and its subclasses.

You define the invariant contract through one or more ad hoc methods. These are instance methods, private, returning void and decorated with a special attribute—the ContractInvariantMethod attribute. In addition, the invariant methods aren’t allowed to contain code other than the calls necessary to define invariant conditions. For example, you can’t add any kind of logic in invariant methods, whether pure or not. You can’t even add logic to simply log the state of the class. Here’s how to define an invariant contract for a class:

public class News {
  public String Title {get; set;}   
  public String Body {get; set;}

  [ContractInvariantMethod]
  private void ObjectInvariant()
  {
    Contract.Invariant(!String.IsNullOrEmpty(Title));
    Contract.Invariant(!String.IsNullOrEmpty(Body));
  }
}

The News class puts as invariant conditions that Title and Body will never be null or empty. Note that for this code to work, you need to enable full runtime checking in the project configuration for the various builds as appropriate (see Figure 1).

Invariants Require Full Runtime Checking for Contracts

Figure 1 Invariants Require Full Runtime Checking for Contracts

Now try the following simple code:

var n = new News();

You’ll be surprised to receive a contract failed exception. You successfully created a new instance of the News class; it’s bad luck it was in an invalid state. A new perspective of invariants is required.

In DDD, invariants are associated with the concept of a factory. A factory is just a public method responsible for creating instances of a class. In DDD, each factory is responsible for returning instances of domain entities in a valid state. The bottom line is that when you use invariants, you should guarantee that conditions are met at any given time.

But what specific time? Both DDD and the actual implementation of Code Contracts agree that invariants be checked at the exit from any public method, including constructors and setters. Figure 2 shows a revised version of the News class that adds a constructor. A factory is the same as a constructor except that—being a static method—it can be given a custom and context-sensitive name and result in more readable code. 

Figure 2 Invariants and Invariant-Aware Constructors

public class News
{
  public News(String title, String body)
  {
    Contract.Requires<ArgumentException>(
      !String.IsNullOrEmpty(title));
    Contract.Requires<ArgumentException>(
      !String.IsNullOrEmpty(body));

    Title = title;
    Body = body;
  }

  public String Title { get; set; }
  public String Body { get; set; }

  [ContractInvariantMethod]
  private void ObjectInvariant()
  {
    Contract.Invariant(!String.IsNullOrEmpty(Title));
    Contract.Invariant(!String.IsNullOrEmpty(Body));
  }
}

The code that consumes the class News can be the following:

var n = new News("Title", "This is the news");

This code won’t throw any exception because the instance is created and returned in a state that meets invariants. What if you add the following line:

var n = new News("Title", "This is the news");
n.Title = "";

Setting the Title property to the empty string puts the object in an invalid state. Because invariants are checked at the exit of public methods—and property setters are public methods—you get an exception again. It’s interesting to note that if you use public fields instead of public properties, then invariants aren’t checked and the code runs just fine. Your object, however, is in an invalid state.

Note that having objects in an invalid state isn’t necessarily a source of trouble. In large systems, however, to stay on the safe side, you might want to manage things so you automatically get exceptions if an invalid state is caught. This helps you manage development and conduct your tests. In small applications, invariants may not be a necessity even when some emerge from the analysis.

Although invariants must be verified at the exit from a public method, within the body of any public method the state can be temporarily invalid. What matters is that invariants hold true before and after the execution of public methods.

How do you prevent the object from getting into an invalid state? A static analysis tool such as the Microsoft Static Code Checker would be able to detect that a given assignment is going to violate an invariant. Invariants protect you from broken behavior but can also help identify poorly specified inputs. By specifying those properly, you can more easily find bugs in the code using a given class.

Contract Inheritance

Figure 3 shows another class with an invariant method defined. This class can serve as the root of a domain model.

Figure 3 Invariant-Based Root Class for a Domain Model

public abstract class DomainObject
{
  public abstract Boolean IsValid();

  [Pure]
  private Boolean IsValidState()
  {
    return IsValid();
  }

  [ContractInvariantMethod]
  private void ObjectInvariant()
  {
    Contract.Invariant(IsValidState());
  }
}

In the DomainObject class, the invariant condition is expressed through a private method declared as a pure method (that is, not altering the state). Internally, the private method calls an abstract method that derived classes will use to indicate their own invariants. Figure 4 shows a possible class derived from DomainObject that overrides the IsValid method.

Figure 4 Overriding a Method Used by Invariants

public class Customer : DomainObject
{
  private Int32 _id;
  private String _companyName, _contact;

  public Customer(Int32 id, String company)
  {
    Contract.Requires(id > 0);
    Contract.Requires(company.Length > 5);
    Contract.Requires(!String.IsNullOrWhiteSpace(company));

    Id = id;
    CompanyName = company;
  }
  ...
  public override bool IsValid()
  {
    return (Id > 0 && !String.IsNullOrWhiteSpace(CompanyName)); 
  }
}

The solution seems elegant and effective. Let’s try to get a new instance of the Customer class passing valid data:

var c = new Customer(1, "DinoEs");

If we stop looking at the Customer constructor, everything looks fine. However, because Customer inherits from DomainObject, the DomainObject constructor is invoked and the invariant is checked. Because IsValid on DomainObject is virtual (actually, abstract) the call is redirected to IsValid as defined on Customer. Unfortunately, the check occurs on an instance that hasn’t been completely initialized. You get an exception, but it’s not your fault. (In the latest release of Code Contracts, this issue has been resolved and invariant checking on constructors is delayed until the outermost constructor has been called.)

This scenario maps to a known issue: don’t call virtual members from a constructor. In this case, it happens not because you directly coded this way, but as a side effect of contract inheritance. You have two solutions: dropping the abstract IsValid from the base class or resorting to the code in Figure 5.

Figure 5 Overriding a Method Used by Invariants

public abstract class DomainObject
{
  protected Boolean Initialized; 
  public abstract Boolean IsValid();

  [Pure]
  private Boolean IsInValidState()
  {
    return !Initialized || IsValid();
  }

  [ContractInvariantMethod]
  private void ObjectInvariant()
  {
    Contract.Invariant(IsInValidState());
  }
}

public class Customer : DomainObject
{
  public Customer(Int32 id, String company)
  {
     ...
    Id = id;
    CompanyName = company;
    Initialized = true;
  }
     ...
}

The Initialized protected member acts as a guard and won’t call into overridden IsValid until the actual object is initialized. The Initialized member can be a field or a property. If it’s a property, though, you get a second tour of the invariants—which isn’t strictly necessary, as everything already has been checked once. In this respect, using a field results in slightly faster code.

Contract inheritance is automatic in the sense that a derived class automatically receives the contracts defined on its base class. In this way, a derived class adds its own preconditions to the preconditions of the base class. The same occurs for postconditions and invariants. When dealing with an inheritance chain, the intermediate language rewriter sums up contracts and calls them in the right order where and when appropriate.

Be Careful

Invariants aren’t bulletproof. Sometimes invariants can help you in one way and cause problems in another, especially if used in every class and in the context of a class hierarchy. Although you should always endeavor to identify invariant logic in your classes, if implementing invariants hits corner cases, then I’d say you’d better drop them from implementation. However, keep in mind that if you hit corner cases, they’re likely due to complexity in the model. Invariants are the tools you need to manage implementation problems; they aren’t the problem themselves.

There’s at least one reason why summing up contracts across a class hierarchy is a delicate operation. It’s too long to discuss it here, but it makes good fodder for next month’s article.


Dino Esposito is the author of “Programming Microsoft ASP.NET 4” (Microsoft Press, 2011) and coauthor of “Microsoft .NET: Architecting Applications for the Enterprise” (Microsoft Press, 2008). Based in Italy, Esposito is a frequent speaker at industry events worldwide. You can follow him on Twitter at twitter.com/despos.

Thanks to the following technical experts for reviewing this article: Manuel Fahndrich and Brian Grunkemeyer