Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

Clay: malleable C# dynamic objects – part 1: why we need it

Bertrand Le Roy, d'après Mucha When trying to build the right data structure in Orchard to contain a view model to which multiple entities blindly contribute, it became obvious pretty fast that using a dynamic structure of sorts was a must.

What we needed was a hierarchical structure: a page can have a list of blog posts and a few widgets, each blog post is the composition of a number of parts such as comments, comments have authors, which can have avatars, ratings, etc.

That gets us to the second requirement, which is that multiple entities that don’t know about each other must contribute to building that object graph. We don’t know the shape of the graph in advance and every node you build is susceptible to being expanded with new nodes.

The problem is that C# static types are not that much fun to build with those requirements.

You could use an XML DOM kind of API with ChildNodes and Attributes collections and NodeName and Value properties and that would absolutely work.

But I think most people would agree that any long term exposure to this style of API is a serious reason for depression that has sucked the will to live out of so many developers we don’t want to go there unless a gun is pointed to our heads.

The main reason why those APIs are so dreadfully boring is that they give you access to the metadata first and hide access to the actual data (which is what you really care about) under secondary APIs such as Value.

The value of a node in an object graph is the one thing you care about the most. The second thing you want easy access to is the children of the node. You want to be able to access them by index or by name.

Honestly, which one would you rather write?

node.Attributes["rating"].Value

or:

node.rating

Yeah, I thought so. The first option feels almost like using reflection to do simple property dereferencing.

OK, so it should be clear by now that the reason why XML APIs are so un-fun in C# is that static languages hate unpredictability and want to know everything about an object at compile-time. They accept what is known in advance (nodes have meta-data that is stable in structure) and relegate what’s unknown to properties.

In other terms, you end up with the real object being a property of the meta-data structure, whereas the meta-data should be a property of the object.

Before I conclude, I want to say a word about object initializers, which have been around for a while and are commonly used to build fuzzy option parameters like this:

Html.TextBoxFor(m => m.CurrentUser, new {
title = "Please type your user name",
style = "float:right;"
})

It should be noted that these anonymous objects, while very flexible at creation time, are basically constants so once you’ve built them, you cannot add new properties or methods to them, which makes them unsuitable for our use-case.

Fortunately for us, C# 4.0 has a great new keyword ready for all kinds of abuse: dynamic.

In part 2, I’ll show how Clay, a small library that Lou wrote, is solving our problem in a very nice and elegant way.

The Clay library: http://clay.codeplex.com

Part 2:
http://weblogs.asp.net/bleroy/archive/2010/08/18/clay-malleable-c-dynamic-objects-part-2.aspx

Comments

Mike Hamrah said:

Really interesting stuff going on here.  This functionality combined with document store databases will open a whole new world to C# programmers.

# August 19, 2010 11:55 AM

Bertrand Le Roy said:

mmm, no, it's still there. Last checkin is from Sept. 8th too.

# September 27, 2010 3:13 PM

Donald said:

I would choose:

node.Attributes["rating"].Value

because then I could make it:

node.Attributes[someVariable].Value

and have it do other work.

# May 9, 2011 8:45 PM

Bertrand Le Roy said:

@Donald: you can get that result by implementing your own Clay behavior.

# May 10, 2011 12:02 AM