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:
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:
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).