How C# new dynamic type can simplify access to late bound COM object


A couple of years ago I got an interesting task. I had to develop a public web service which utilized internally a third-party COM object. Sounds easy, the concept of COM Interop exists in .NET since the first release, so I didn't expect any difficulties on my way.

Just to be more specific let's say we have a very simple VB6 COM object "MyProject.MyClass" having a single method Add, taking two Integer parameters and returning a sum of them:

Public Function Add(first As Integer, second As Integer) As Integer
  Add = first + second
End Function

I've started a new Visual Studio project, added a reference to the COM object and wrote the following code:

using System;
namespace ComTest
{
  class Program
  {
      static void Main(string[] args)
      {
          MyProject.MyClass comObject = new MyProject.MyClass();
          short sum = comObject.Add(1,2);
          Console.Out.WriteLine("Early binding. Sum = " + sum);
          Console.ReadLine();
      }
  }
}

It worked. But after some time I realized that the third-party COM object is updated on nearly a monthly basis. And the COM object has been probably developed in VB6 with no version compatibility settings, resulting in constantly changing GUIDs even when the interface signatures haven't changed. As a result my program started to crash showing the following message:

An unhandled exception of type 'System.InvalidCastException' occurred in ComTest.exe

I had two options: either recompile my web service each time I receive a new COM object or to use late binding. Obviously I went for the last option.
My C# code looked like this:

using System;
using System.Reflection;

namespace ComTest
{
  class Program
  {
      static void Main(string[] args)
      {
          System.Type objType = System.Type.GetTypeFromProgID("MyProject.MyClass");
          object comObject = System.Activator.CreateInstance(objType);

          object[] oParms = new Object[] { 1, 2 };
          short sum = (short)objType.InvokeMember("Add", BindingFlags.InvokeMethod, null, comObject, oParms);
          Console.Out.WriteLine(sum);
          Console.ReadLine();
      }
  }
}

It worked, but imagine if you have not just one method in COM object but many of them. Building every time a parameter list and calling InvokeMember is not the most pleasant way to spend your time in the office. And there was no other option until Visual C# 2010. Thanks to the new dynamic type, it is possible now to declare an object of a type that bypasses static type checking. At compile time, an element that is typed as dynamic is assumed to support any operation. Therefore, we can write the following code now:

using System;
using System.Reflection;

namespace ComTest
{
  class Program
  {
      static void Main(string[] args)
      {
          System.Type objType = System.Type.GetTypeFromProgID("MyProject.MyClass");
          dynamic comObject = System.Activator.CreateInstance(objType);

          short sum = comObject.add(1, 2);
          Console.Out.WriteLine("Late binding with dynamic type. Sum = " + sum);
          Console.ReadLine();
      }
  }
}

So we are using now the same method signatures as in first example without a need to use a call to InvokeMember. However, if the method signature is not valid, errors are caught at run time. How will it help me? Very simple. First I start developing my application by adding a reference to the COM object. It's so easy to use .NET wrappers, generated for you by Visual Studio. When I am almost ready to deploy, I remove the reference and use GetTypeFromProgID instead. 

That's it.


Similar Articles