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).
I don’t think that’s bad at all! Don’t listen to the nay sayers!
As for xpath, you could implement a linq provider for it and blow xpath out of the water.
I did something similar only with DynamicObject:
http://www.justnbusiness.com/post/2009/07/08/The-Illusion-of-Strongly-Typed-XML-with-C.aspx
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.
Just found out over the weekend a similar concept is already implemented in PowerShell…
You should go check it out.
One nice thing about the powershell implementation is how each “node” returned is still a .net xml object of some kind.
Lots of good examples out there “goog – Powershell Xml”
EX: http://www.pluralsight-training.net/community/blogs/dan/archive/2006/11/25/42506.aspx
[…] recently attended Twin Cities Code Camp 8.0. One of the speakers, Aaron Erickson, spoke on some of the new C# 4.0 features. He showed how you could use the dynamic keyword to […]
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.
[…] about how to use the dynamic features for parsing CSV files. The same technique can be used to parse XML files as well. If you’ve used DataSets in the past, this is another such framework which currently uses […]
[…] about how to use the dynamic features for parsing CSV files. The same technique can be used to parse XML files as well. If you’ve used DataSets in the past, this is another such framework which currently uses […]