Using Dynamic with C# to read XML

On April 10th (less than 1 week away), I am doing an updated version of my talk at Twin Cities Code Camp about using dynamic with C#.

One core technique I am seeking to demonstrate is to use the concept of a dynamic XML reader as a more human readable way to use XML content in from C# or any other dynamic language.

Consider the following usage scenarios:

http://pastie.org/904555

What we would like is an object that will use dynamic in C# to make it so that we can read XML without having to think about all the nasty mechanics of search, XPath, and other stuff that isn’t “I am looking for the foobar configuration setting” or whatever it is we are looking for in the XML we want to look at.  The following is the basic spiked implementation:

http://pastie.org/904557

The real hard part was figuring out the mechanics of how DynamicMetaObject actually does it’s work.  Doing a dynamic object, if you are not going to do it the easy way and simply inherit from dynamicobject, means you are going to write two classes:

  • Something that implements IDynamicMetaObjectProvider
  • Something that inherits from DynamicMetaObject

The job of IDynamicMetaObjectProvider – at least as far as I can tell – is simply to point to the right DynamicMetaObject implementation, and somehow associate something with it that will potentially drive how the dynamic object will respond to various calls.  Most of the interesting stuff happens in DynamicMetaObject, where we get to specify how various kinds of bindings will work.

In a simple case like this where we are doing everything with properties, we merely need to override BindGetMember.  The return value of BindGetMember will generally be another DynamicMetaObject derived class.

Generally, DynamicMetaObjects take three parameters on construction:

  • A target expression
  • A binding restriction (something that tells the object a little about what it has – not entirely sure why…)
  • The actual thing to pass back

In the way I am using this, there are three main ways we return.  If we find we can resolve the property call to be a string, we are just going to wrap the string in a constant expression, specify a type restriction on string, and send that back.  If we are resolving to another XElement that has sub-items – we are going to wrap the XElement into a new DynamicXmlMetaObject – as a means to allow for further dot notation to get at sub-elements.  Lastly, if we have a group of the same item, we are going to return an array of either wrapped strings, or wrapped DynamicXmlMetaObjects.  Managing through these three cases is where most of the complexity is.

This is a work in progress – and I have already been told by some that this is a bad idea (i.e. “why not XPath?”, “that looks dangerous”, and “what if the Republicans use this?”).  But certainly, for certain kinds of problems, I can definitely see myself using this kind of thing to remove lots of Linq to XML plumbing code! (note, some work to integrate this and perhaps somehow combine this with XPath queries will probably happen).

Advertisement
Using Dynamic with C# to read XML

7 thoughts on “Using Dynamic with C# to read XML

  1. Aaron Erickson says:

    Neat work Justin – was thinking of going with the strict inherit from DynamicObject approach – but since I wanted to learn how IDynamicMetaObject provider works (my real reason for writing this in the first place), I opted to go the “hard way”.

    They kinda seem to get you to the same place though. I have to think through why you go with one over the other.

  2. vc says:

    I found one problem with your code samples. It caches the used xml-file. When you try to read other xml-file, it uses the first one. Is there simple way to flush the cache, so you can use this code for several xml-files.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s