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

Miha Markic

About me
Righthand
 
Microsoft MVP
 
Developer Express' DXSquad
INETA Country Leader for Slovenia
INETA Country Leader for Slovenia

Slovene Developer Users Group Lead
Friends of Red-Gate
LLBLGenPro Partner

Miha currently works as a free lance consultant and software developer specialized in .net area.
He graduated in Computer and information science at the University of Ljubljana, Slovenia. He has accumulated experience in various programming languages such as Java, Visual Basic 3-6 (MCP), Visual C++, Delphi, C# and VB.Net through years.
He has experience in practically all (technical) stages of project development, including planning, framework development, user interface, business processes, as well as testing and documenting. He has worked on big and small projects in Slovenia and abroad (e.g. participated in completing level 3 IS for the Nucor steel plant, Hertford, USA).
Currently he enjoys programming in .net environment using C#. Since 2000 he has been active in Developer Express' DX Squad and has been ECDL trainer and tester. He also gives lectures on conferences and other events in Slovenia.

Month List

Tag cloud

Most comments

Dan Dan
4 comments
ca Canada
Thomas Thomas
3 comments
de Germany
Sebastian Sebastian
1 comments
ca Canada

RecentComments

Comment RSS