InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

.NET 4 Feature Focus: Code Contracts

Posted by Jonathan Allen on Nov 09, 2008

Sections
Development,
Architecture & Design
Topics
.NET ,
Unit Testing ,
Language Design
Tags
Spec# ,
Quality

Last year we started talking about Spec#, a language based on C# that supports design by contract. Design by contract builds on top of concepts like static typing, where certain actions cannot be performed unless it can be verified at compile time. Contracts usually take the form of pre- and post-conditions such as a parameter or return value never being null or only containing a certain range of values.

Rather than force developers to learn a whole new language such as Spec#, Microsoft is working on a language-agnostic library that can be leveraged by any .NET language. In some ways contracts look like assertions, but they are very different under the covers. Contracts are supported by a combination of static code analysis, which can be both inside and outside the compiler, as well as by testing frameworks. They are also executable, meaning they behave like assertions when running a debug build. Consider this first example:

string GetDescription(int x){
Contract.Requires(x>0);
Contract.Ensures(Contract.Result<string>() != null);

Looking at just the signature, developers only get the static type information "GetDescription requires an integer and returns a string". With the contracts, both developers and tools know "GetDescription requires a positive integer and returns a string that is never null".

In addition to explicit contracts, the contract checker can also support implicit contracts. One such example is division by zero. If a class includes a division of integers where the divisor is a variable, then all code paths must ensure that the variable is never zero or a warning is issued. If the variable in question is a property on a unsealed class, this would require checking in every subclass as well. There are also implicit contracts for dereferencing nulls and array indexes.

To make this easier, there is the concept of an ObjectInvariant method. This special method, which only contains contracts, is injected into the end of each method call to ensure the object's state remains consistent. It is important to note that this applies to all methods, including those in subclasses from other assemblies.

Another time saving device is easy access to old values. In this example the Ensures contract is used in conjunction with the OldValue syntax to make certain that the collection's count property is incremented.

Public Sub Add(value as Object) 
Contract.Ensure(Count = Contract.OldValue(Count) + 1) 

Even though the contract is written at the top of the method, it will automatically be moved to just before the Return statement by the compiler. As there is some overhead for storing the old value of Count, this sort of check will only occur in debug builds.

In order to support library developers, release builds include a reference assembly. For example, the Widgets.dll assembly would have the bulk of its contracts extracted and placed in the assembly Widgets.Contracts.dll. This allows client developers to use the faster release-style builds while still leveraging the contracts created by the library developers.

One of the more interesting features is that contracts do not just apply to concrete functions. Even interface and abstract methods with no other implementation detail can have contracts. This is done by creating a reference implementation of the interface whose sole purpose is to hold contracts. This reference implementation is linked back to the interface by attributes.

There are no restrictions on the contents of a contract. Since the same contracts are used for both static and runtime checking, a complex constraint that cannot be evaluated by one may still be checked by the other. Contracts can also be extracted by documentation generators.

For more information on Contracts in .NET 4, check out the first half of this PDC keynote.

contracts and business logic by Fernando Felman Posted
Re: contracts and business logic by Jonathan Allen Posted
Re: contracts and business logic by Fernando Felman Posted
Re: contracts and business logic by Fredrik Klintebäck Posted
Re: contracts and business logic by Jeff Santini Posted
Delphi Prism (ex Oxygene) already support this; no need to wait for .NET 4 by El Cy Posted
  1. Back to top

    contracts and business logic

    by Fernando Felman

    I think this technology is a great stability and maintenance boost but it comes with huge risk: the potential to make wonderful spaghetti out of the business rules.

    When dealing with pure algorithms this technology is great – it will ensure the input you get matches the meaning you had in mind when creating the function. This will mostly be the case for libraries and frameworks which deals with generic concerns such as data structure (arrays, trees) or high level concepts (mathematical or graphical library).

    The problem for such a technology is that it makes it too easy to put the business logic all the system. Think of a simple scenario: a Customer object that have an ID, a name and some orders. Using this technology you can easily contract the ID for a particular format, the name to be not empty and the orders to be non-negative. You’d also want to maintain those constraints throughout the systems so if you’ve a function dealing with ID you’d probably decorate its inputs with the same contracts. But then business rules changed causing the contracts to change which might have a known down effect on a big systems as you’ll have to modify the contracts throughout the whole system.

    True, it is possible to prevent such problem i.e. treat business rules in a different way than the more abstract rules (e.g. business rules in an engine rules and abstract constraints using code contracts) but this distinction is not trivial and I’m quite concerned that some developers might overuse the power given by this technology.

    In essence, before incorporating this in my projects I’d like to see some supporting tools to make sure it’s not being misused (FxCop or something similar can do the trick).

  2. Back to top

    Delphi Prism (ex Oxygene) already support this; no need to wait for .NET 4

    by El Cy

    Bellow I included some interesting links regarding Delphi Prism

    Delphi Prism Language
    prismwiki.codegear.com/wiki/Language

    Delphi Prism vs. C#
    prismwiki.codegear.com/wiki/Delphi_Prism_vs._CS...


    Delphi Prism
    www.codegear.com/products/delphi/prism

    Delphi Prism - new language features for Delphi .NET developers
    blogs.codegear.com/andreanolanusse/2008/10/29/d...

    Interview with marc hoffman: "Delphi Prism - Visual Studio Pascal For .NET"
    www.bitwisemag.com/2/Delphi-Prism-Visual-Studio...

  3. Back to top

    Re: contracts and business logic

    by Jonathan Allen

    But then business rules changed causing the contracts to change which might have a known down effect on a big systems as you’ll have to modify the contracts throughout the whole system.


    You are probably going to have to propagate those business rules throughout your code base anyways. The fact that they have contracts associated with them may just end up making it easier to find all the places that need to be changed.

  4. Back to top

    Re: contracts and business logic

    by Fernando Felman

    But then business rules changed causing the contracts to change which might have a known down effect on a big systems as you’ll have to modify the contracts throughout the whole system.


    You are probably going to have to propagate those business rules throughout your code base anyways. The fact that they have contracts associated with them may just end up making it easier to find all the places that need to be changed.


    Very true and that's why I think code contract has the potential to create mess, but I wouldn't say not using them will prevent the mess. Basically, code contracts gives developers from all layers (data, business logic, presentation, proxies, etc.) the power to declare rules in the source-code. Though a powerful capability by itself, I'm concern it’s too easy to misuse it especially since it’s a new technology with no governance usage or best practices.
    I'll try to put it in a different way. If you have no code contracts you're more likely to plan in advance how business rules are to be used throughout all layers; and so you're less likely to give developers from all layers the ability to declare business rules in the code. This in turn has the potential to enable less painful changes to the business rules as you can anticipate where to find those rules.

  5. Back to top

    Re: contracts and business logic

    by Jeff Santini

    But then business rules changed causing the contracts to change which might have a known down effect on a big systems as you’ll have to modify the contracts throughout the whole system.


    You are probably going to have to propagate those business rules throughout your code base anyways. The fact that they have contracts associated with them may just end up making it easier to find all the places that need to be changed.


    Why are you going to propogate your business rules everywhere? Wrap them in a type and pass it everywhere, then your business rules live in only one place. Eric Evans specification that he discusses in Domain Driven Design is a good example. Maybe I have just been lucky but it has been many years since I have seen the need to spray business rules throughout my code base.

  6. Back to top

    Re: contracts and business logic

    by Fredrik Klintebäck

    ...Though a powerful capability by itself, I'm concern it’s too easy to misuse it especially since it’s a new technology with no governance usage or best practices.
    ...

    The technology isn't new, it has been around at least two decades. Most notably, in the programming language Eiffel, invented by Bertrand Meyer in 1985 I think.

Educational Content

New-age Transactional Systems - Not Your Grandpa's OLTP

John Hugg discusses high volume transaction processing applications with high and low frequency profiles, and how VoltDB can be used for that purpose.

Cool Code

Kevlin Henney examines code samples to see what can be learned from them starting from the premise that one won’t write great code unless he knows how to read it.

Collaboration: At the Extremities of Extreme

Jason Ayers share the observations he made watching a team of developers collaborating in real time on the same code base, pushing XP, pair programming and continuous integration to their extremes.

Yesod Web Framework

Michael Snoyman presents Yesod, a web framework written in Haskell and containing a web server, templating, ORM, libraries (templating, gravatar, etc.).

Transactions without Transactions

Richard Kreuter and Kyle Banker on how to avoid classical RDBMS transactional systems by using compensation mechanisms, transactional messaging or transactional procedures.

Attila Szegedi on JVM and GC Performance Tuning at Twitter

Attila Szegedi talks about performance tuning Java and Scala programs at Twitter: how to approach GC problems, the importance of asynchronous I/O, when to use MySQL/Cassandra/Redis, and much more.

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.