[TestFixture]
public class ExpandoToMessageConverterTests
{
/// <summary>
/// CanConvertEvent
/// </summary>
[Test]
public void CanConvertEvent()
{
dynamic expandoEvent = new ExpandoObject();
expandoEvent.PropertyOne = "pROPERTYoNE";
expandoEvent.PropertyTow = "pROPERTYtWO";
XElement xEvent=ExpandoToMessageConverter.ExpandoToMessageEvent(expandoEvent);
/*var xEvent = new XElement("event",
new XElement("properties",
new XElement("property",
new XAttribute("name", "pROPERTYoNE"),
new XAttribute("value", "someVal")),
new XElement("property",
new XAttribute("name", "pROPERTYtWO"),
new XAttribute("value", "BLAH"))));*/
Assert.IsNotNull(xEvent);
var properties = new List<XElement>(xEvent.Descendants("properties"));
Assert.AreEqual(1,properties.Count);
var value = ((IEnumerable)xEvent.XPathEvaluate("properties/property")).Cast<XElement>();
Assert.AreEqual(2, value.Count());
}
In the code above I create the same xml in different ways (one, explicit, is commented out). The other one is using the ExpandoToMessageEvent(ExpandoObject), which returns a XElement. Here is the mystery for me:
Obviously, I can make it work. But the question is: why does 'dynamic' word throw CLR off?
I decided to check a couple more things and here is what I found: If i pass a new ExpandoObject() to the function then the type of xEvent in the "var xEvent = ExpandoToMessageConverter.ExpandoToMessageEvent(new ExpandoObject())" is determined correctly and CLR is happy. However, if I say "dynamic blah = new ExpandoObject()" and then " var xEvent=ExpandoToMessageEvent(blah)", the type of xEvent is not determined correctly (I guess) and CLR does not seem to consider extension methods for XElement.
Overload resolution of a dynamic invocations does not consider extension methods.
Determining what extension methods are available on a given call requires knowing what "using" directives were in force at the call site. We had no previously existing mechanism for persisting this information into the call site; we did not have the budget to design, implement, test and document a new mechanism and still ship C# 4 on time. We therefore cut that portion of the feature.