Dynamic Objects

The IDynamicMetaObjectProvider interface represents an object that can be late bound.

Microsoft supplies to implementations of this interface out of the box. DynamicObject and ExpandoObject.

DynamicObject

The DynamicObject is mean’t to be used as a base class for the user’s own dynamic object and hence has a protected constructor. The idea is that we can create our own dynamic object and handle any attempted access to member properties or methods etc. at runtime.

For example here’s an implementation of a dynamic object which adds (at runtime) a method which takes no arguments and returns a string

public class MyObject : DynamicObject
{
   public override bool TryGetMember(
            GetMemberBinder binder, out object result)
   {
      result = null;
      if (binder.Name == "GetName")
      {
         result = new Func<string>(() => "Hello World");
         return true;
      }
      return false;
   }
}

If we wanted to handle a property named GetName we’d simply return a string, not a function. The TryGetMember is used for methods with no arguments or get properties, when arguments are supplied to a method we should override TryInvokeMember.

ExpandoObject

Unlike DynamicObject an ExpandoObject can be instantiated and then we can add methods and properties to it via it’s IDictionary interfaces.

So for example, let’s create an ExpandoObject and add a new method

dynamic d = new ExpandoObject();

((IDictionary<string, object>)d).Add("GetName", new Func<string>(() => "Hello World"));

Console.WriteLine(d.GetName());

As you can see we must ofcourse declare our variable as dynamic otherwise the use of GetName will cause the compilation error

System.Dynamic.ExpandoObject’ does not contain a definition for ‘GetName’ and no extension method ‘GetName’ accepting a first argument of type ‘System.Dynamic.ExpandoObject’ could be found (are you missing a using directive or an assembly reference?)

We also need to cast the instance to IDictionary<string, object> as access to the Add method needs to go through an explicit interface.

So as you see, we can add to the ExpandoObject at runtime, unlike a DynamicObject derived class where only the derived class would be able to add to the object at runtime (obviously assuming we don’t add methods to allow this ourselves).