Month: January 2008

C# by Contract – Using Expression Trees

Last time I created a simple, but powerful, little design by contract library in C# 3.0. It took hardly any lines of code, and covered a broad range of possible usage scenarios. See here, for more on DBC. One thing that bothered me was the fact that if something failed a check, it wouldn’t tell what went wrong. I had a little free time today, so I thought I’d fix that. I wanted the exceptions it threw to have the text of the check we were performing. Developers need to see exactly what test failed. Generic “assertion failed” error messages are useless.

In my previous efforts at .NET DBC, I used strings to pass around the predicate body that I wished to evaluate. That allowed me to have a copy of the text handy, but with lots of drawbacks. In those frameworks, I created a new class that derived from the one being tested, but with the predicates inserted at the beginning and end of the methods they were attached to. That allowed me to do things like this:

[Requires("arg1 > 10")]
[Requires("arg2 < 100")]
[Ensures("$after(Prop1) == $before(Prop1) + 1")]
public void TestMethod(int arg1, int arg2, string arg3)
{
    Prop1 = Prop1 + 1;
    System.Diagnostics.Debug.WriteLine("MyTestClass.TestMethod.Prop1 == " + prop1.ToString());
}

This let me to test private fields and properties, but on the other hand it stopped me from testing sealed classes. There’s trade-offs no matter what you do unless you control the compiler, as is the case of Spec#, Eiffel or D. The attribute based approach is not dissimilar to Spec#, where a contract specification is part of the method signature rather than in the body of the method.

int BinarySearch(object[ ]! a, object o, int lo, int hi)
    requires 0 <= lo && lo <= hi && hi <= a.Length;
{ . . . }

The difference is that Spec# uses syntactical enhancements, whereas I used Attributes. As I mentioned in another post, you can’t use lambda functions in Attributes, nor could you use Expression trees based on lambda functions because the attribute itself cannot be generic. Another major drawback of the textual approach shown earlier is that it isn’t type-safe. You could type any old garbage into that string, and you’d never know till run-time. You don’t get intellisense either. We need a better way.

Expression trees are great for what we want, they are strongly typed, they can be assigned from lambda functions and they needn’t be compiled until they’re needed. Another cool thing is that the changes needed to use lambda expressions are trivial. Here’s the Require extension method I showed you last time. It uses Expressions now.

public static void Require<T>(this T obj, Expression<Func<T, bool>> pred)
{
    var x = pred.Compile();
    if (!x(obj))
        throw new ContractException(pred.ToString());
}

All I had to do was convert the Func<T, bool> into an Expression<Func<T, bool>>. The compiler, seeing the method signature, knows that it needs to do some background conversion. It doesn’t convert and pre-compile the lambda function that you pass into the extension method. Instead it first converts it to an expression tree. The Expression<Func<T, bool>> has a Compile method that will convert it to an anonymous method, which we call just before invoking it. You may be wondering why we would bother?

Because Expression<Func<T, bool>> also overrides ToString() giving the source code of the lambda function that it was created from. That’s so cool! Now I can pass the code I was trying to run into the exception class if the code fails!. Here’s the kind of output you get if the check fails.

TestCase ‘Tests.TestPredicates.MyFailingMethod’
failed: Contracts.ContractException : x => (value(Tests.TestPredicates).MyInt = x.before().MyInt)

That’s more readable than a plain old ‘ApplicationException’, don’t you think?  The predicates needn’t be one-liners either; you can have very complex predicates in this system too. Here’s an example from another project I’m working on. The use of scopes is more like the DBC implementation in the D Programming Language.

public bool Insert(string location, string xmlFragment)
{
    this.Require(x => !string.IsNullOrEmpty(location));
    this.Require(x => !string.IsNullOrEmpty(xmlFragment));

    XDocument fragDoc = XDocument.Parse(xmlFragment);
    object tmpInsertPoint = LobDocument.XPathEvaluate(location);
    bool result = false;

    using (new PredicateScope(this, fragDoc, tmpInsertPoint))
    {
        this.Ensure(x => tmpInsertPoint != null);

        if (tmpInsertPoint != null)
        {
            if (tmpInsertPoint is XElement)
            {
                XElement insertPoint = tmpInsertPoint as XElement;
                insertPoint.Add(fragDoc);
                result = true;
            }
        }

        this.Ensure(x =>
            {
                XElement originalInsertPoint = tmpInsertPoint.before() as XElement;
                XElement currentInsertPoint = tmpInsertPoint as XElement;
                int countbefore = originalInsertPoint.Elements(fragDoc.Root.Name).Count();
                int countafter = currentInsertPoint.Elements(fragDoc.Root.Name).Count();
                return countafter == (countbefore + 1);
            });
    }
    return result;
}

This is a fairly advanced use of lambdas and expression trees, but it certainly doesn’t plumb the depths of what we could do. Those of you who’ve read some of the stuff I did in ’06 and ’07 on the internals of LINQ will remember that expression trees will be storing references to all the properties and other parameters of the lambda function. That means we can add them to the ContractException. We can also show what values they were before and after the operation. Perhaps next time I’ll explore what can be done with all that extra data we’ve now got.

Till then, enjoy!

Complex Assertions using C# 3.0

Recently I attempted to implement a declarative predicate checking system to allow design by contract (DBC) within C# 3.0. I was not successful due to a limitation in the kind of parameters one can pass to an Attribute constructor in .NET (no lambdas). I thought I’d just follow that up with a simpler model based on extension methods.

public static class Predicates
{
    public static void Assert<T>(this T obj, Func<T, bool> pred)
    {
        if (!pred(obj))
            throw new ApplicationException();
    }
}

This simple extension method can be attached to any object allowing Ensures and Requires like this.

int MyIntProp{get;set;}
public void MyMethod()
{
    this.Assert(x => x.MyIntProp < 10);
    MyIntProp += 10;
    this.Assert(x => x.MyIntProp >= 10);
}

This is a nice clear implementation that is good for validation. But I think that I can extend it further by exploiting serialization of snapshots within a scope to allow before/after analysis within the scope. Here’s what I want to be able to write:

public void MyBetterMethod()
{
    this.Require(x => x.MyIntProp < 10);
    MyIntProp += 10;
    this.Ensure(x => x.MyIntProp == x.before().MyIntProp + 10);
}

Well, my recent writings about the Ambient Context pattern might give you a clue about how I would manage the scope. The first thing I need to be able to do is store a snapshot of the object before it gets tested by the Require. I chose an IDisposable object so that I can clean up after myself without the danger of having the serialized guts of objects lying around everywhere.

public class PredicateScope : IDisposable
{
    [ThreadStatic]
    public static Stack<PredicateScope> Scopes = new Stack<PredicateScope>();
    internal readonly Dictionary<object, string> Snapshots = new Dictionary<object, string>();
    internal readonly Dictionary<object, object> DeserializedSnapshots = new Dictionary<object, object>();

    public PredicateScope(params object[] objects)
    {
        foreach (object obj in objects)
        {
            Snapshots.Add(obj, CreateSnapShot(obj));
        }
        Scopes.Push(this);
    }
    static string CreateSnapShot(object obj)
    {
        XmlSerializer serializer = new XmlSerializer(obj.GetType());
        StringWriter sr = new StringWriter();
        serializer.Serialize(sr, obj);
        return sr.ToString();

    }

    public void Dispose()
    {
        Snapshots.Clear();
        Scopes.Pop();
    }
}

You just pass the scope object whatever objects you intend to test later on. It takes snapshots of the objects and stores them away for later reference. It also maintains a stack, so it can be nested. Strictly speaking this is unnecessary, but I figure it might come in handy later on.

My Assertion methods are pretty much the same, but they’re now augmented by a “before” extension method that will get a snapshot keyed to the object it’s extending, and return that instead.

public static class Predicates
{
    public static void Require<T>(this T obj, Func<T, bool> pred)
    {
        if (!pred(obj))
            throw new ApplicationException();
    }

    public static void Ensure<T>(this T obj, Func<T, bool> pred)
    {
        if (!pred(obj))
            throw new ApplicationException();
    }

    public static T before<T>(this T obj) where T : class
    {
        if (obj == null)
            throw new ArgumentNullException("obj cannot be null");

        PredicateScope ctx = PredicateScope.Scopes.Peek();
        if (ctx == null) return default(T);

        if (ctx.DeserializedSnapshots.ContainsKey(obj))
            return ctx.DeserializedSnapshots[obj] as T;
        string serializedObject = ctx.Snapshots[obj];
        XmlSerializer ser = new XmlSerializer(typeof(T));
        XmlReader reader = XmlReader.Create(new StringReader(serializedObject));
        object result = ser.Deserialize(reader);
        ctx.DeserializedSnapshots[obj] = result;
        return result as T;

    }
}

The before method gets the snapshot out of the scope, and returns that. You can then use it in your assertions in exactly the same way as the original object.

[TestFixture, DataContract]
public class MyClass
{
    [DataMember]
    public int MyInt { get; set; }
    [Test]
    public void MyMethod()
    {
        using (new PredicateScope(this))
        {
            this.Require(x => x.MyInt < 10);
            MyInt += 10;
            this.Ensure(x => MyInt == x.before().MyInt + 10);
        }
    }
}

Obviously, for production use you’d have to ensure this stuff didn’t get run by using ConditionalAttribute. It would affect performance. But for debugging it can be a godsend.

Setting up SDB on SQL Server 2005

imageFor the non-Java developer, like me, setting up and configuring SDB can be tricky. While it’s fresh in my mind I’ll commit it to blog so that those who come after will not tear their hair out like I just did.

SDB sits below Jena providing it with database support for a triple store rather than the more restrictive RDF XML file. The benefits of using a database are obvious, but the difficulties are not. the following instructions assume that you are running JRE 1.6, Vista and Cygwin. You need Cygwin to be able to run the batch files that come with SDB. You could probably adapt them to work on DOS, but Cygwin allows you to run the scripts as is.

Checklist:

  1. Get a copy of SDB & put it somewhere handy (I chose C:\etc\downloads\dev\semantic-web\sdb-1.0)
  2. Get a JDBC driver for SQL server.
    1. copy it to the lib dir under SDB. I’m not sure why, but I had to do this  despite the fact that there is an environment var that ought to be enough.
  3. Create a database for your triple store (I called mine TestTripleStore)
    1. Remember that you must use binary collation (I chose Latin1_General_BIN).
    2. Create a user and login for the new database (I chose sdbuser).
      1. Login as that user using SQL Management Studio – in case you need to change the user credentials on first login.
    3. Assign the new user ownership of the new triple store database.
    4. Setup TCP/IP access on your database server.
  4. setup the following environment variables using your .profile or .bashrc file (remember to source the file before you try to do anything)
    SDBROOT=”C:\etc\downloads\dev\semantic-web\sdb-1.0″
    SDB_JDBC=”$SDBROOT\lib\sqljdbc.jar”
    SDB_USER=”sdbuser”
    SDB_PASSWORD=”********”
    Note the use of DOS/Windows style path declarations despite the use of Cygwin – this one always catches me out.
  5. write the SDB configuration file (sdb.ttl) and place it in the $SDBROOT directory. This is straightforward – just modify the server and database name as appropriate:
    @prefix sdb:     <http://jena.hpl.hp.com/2007/sdb#&gt; .
    @prefix rdfs:     <http://www.w3.org/2000/01/rdf-schema#&gt; .
    @prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt; .
    @prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#&gt; .

    # Microsoft SQL Server

    _:c rdf:type sdb:SDBConnection ;
        sdb:sdbType        “MSSQLServer” ;
        sdb:sdbHost        “localhost” ;
        sdb:sdbName        “TestTripleStore” ;
        sdb:driver         “com.microsoft.sqlserver.jdbc.SQLServerDriver”
        .

    [] rdf:type sdb:Store ;
        sdb:layout         “layout2″ ;
        sdb:connection     _:c ;

  6. Create the triple store for SDB:
    sdbconfig –sdb=sdb.ttl create

If all goes according to plan, you should get no errors and the following tables in SQL server.

image