Manage Code ContractClass

The problem

In order to enforce code contracts interface contracts you can create a class that implements that interface and add Contracts clauses in that class. That way every class implementing the interface will have to enforce the same contracts.

Sample

Here is a sample interface I want to enforce.

interface ITubo<T>
    where T : class
{
    T DoSomething<T, X>(T a, X b)
        where T : class, new();
    void Another(object cantBeNull);
    int PositiveValue { get; }
}

First I have to add CodeContracts namespace in my using block:

using System.Diagnostics.Contracts;

To enforce the contracts I will create a class that implements it, like this:

[ContractClassFor(typeof(ITubo<>))]
internal abstract class ITuboContract<T> : ITubo<T>
    where T : class
{
    public int PositiveValue
    {
        get
        {
            Contract.Ensures(Contract.Result<int>() > 0);

            throw new NotImplementedException();
        }
    }
    public T DoSomething<T, X>(T a, X b)
        where T : class, new()
    {
        Contract.Requires(a != null); Contract.Ensures(Contract.Result<T>() != null); 
        throw new NotImplementedException();
    }
    public void Another(object cantBeNull)
    {
        Contract.Requires(cantBeNull != null);

        throw new NotImplementedException();
    }
}

As a last step I need to let know which class implements contracts for my interface. This is done by decorating the interface with ContractClass attribute.

[ContractClass(typeof(ITuboContract<>))]
interface ITubo<T>
....

The whole enchilada looks like this:

[ContractClass(typeof(ITuboContract<>))]
interface ITubo<T>
    where T : class
{
    T DoSomething<T, X>(T a, X b)
        where T : class, new();
    void Another(object cantBeNull);
    int PositiveValue { get; }
}

[ContractClassFor(typeof(ITubo<>))]
internal abstract class ITuboContract<T> : ITubo<T>
    where T : class
{
    public int PositiveValue
    {
        get
        {
            Contract.Ensures(Contract.Result<int>() > 0);

            throw new NotImplementedException();
        }
    }
    public T DoSomething<T, X>(T a, X b)
        where T : class, new()
    {
        Contract.Requires(a != null);
        Contract.Ensures(Contract.Result<T>() != null);

        throw new NotImplementedException();
    }
    public void Another(object cantBeNull)
    {
        Contract.Requires(cantBeNull != null);

        throw new NotImplementedException();
    }
}

While this works just fine it is tedious to code and then manage when interface changes. Imagine a more complex interface.

The solution

The creation of the contract class can be deduced from the interface and so are the ContractClass and ContractClassFor attributes. This work is perfect for CodeRush. There is only a slight problem. CodeRush doesn't implement such a feature. Until now.

Meet ManageCondeContractClass plugin. Thanks goes to Rory Becker (insanely helpful CodeRush guru) who helped with the initial code on which I've built and enhanced the plugin.

Note that the plugin won't insert Contract statements - that's your job. Instead it will generate all code that it can.

Installation

1. If you don’t have CodeRush already installed then do install its Express version which is free or even better, go with full version (which is not free but it is well worth it).

2. Download attached zip file and unpack its content into either [USER]\Documents\DevExpress\IDE Tools\Community\PlugIns or [Program files [x86]]\DevExpress [DX version, i.e. 2009.3]\IDETools\System\CodeRush\BIN\PLUGINS.

Test and use

1. Try copying my sample interface into a source code.

2. Position caret on interface keyword.

3. Click on shortcut or on CodeRush actions popup menu

4. The plugin should generate a class that implements the interface, decorate both class and interface with attribute and insert an using statement if the namespace isn't among existing using statements.

5. Try modifying the interface and repeating the step #3. The members that aren't modified will remain intace on contract class while non matching members will be recreated.

The conclusion

I hope you’ll find this plugin useful. I am starting to use it and it saves me a lot of clicking. And thanks to DXCore framework it was really easy to create it.

Let me know if you have ideas how to enhance it or anything else, all feedback is welcome.

Requirements

  • .net 3.5 or newer
  • CodeRush/DXCore (tested with 11.1.6)
  • Tested with C#, should work with vb.net as well

The bits

1.0.0. (6.8.2011)

Initial release.

My other CodeRush/DXCore plugins

Go To Implementator