Click here to Skip to main content
Click here to Skip to main content

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

, 21 Jan 2011
Rate this:
Please Sign up or sign in to vote.
Explains how the new dynamic type can simplify access to late bound COM objects.

Introduction

A couple of years ago, I got an interesting task. I had to develop a public Web Service which internally utilized 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" with a single method Add, taking two Integer parameters and returning the sum of them:

Public Function Add(first As Integer, second As Integer) As Integer

  Add = first + second

End Function

I 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 starts 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 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 a parameter list every time 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 now using the same method signatures as in the first example without the need to call 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 the .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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Igor Merabishvili
Software Developer (Senior)
Germany Germany
No Biography provided

Comments and Discussions

 
Questionaccess interface and methods Pinmemberabhibio4-Feb-13 1:43 
GeneralAnother option... PinmemberRichard Deeming25-Jan-11 9:29 
GeneralRe: Another option... PinmemberIgor Merabishvili25-Jan-11 23:41 
GeneralRe: Another option... PinmemberRichard Deeming26-Jan-11 1:44 
GeneralMy vote of 5 PinmemberYusuf21-Jan-11 11:05 
GeneralMy vote of 5 PinmemberNemanja Trifunovic21-Jan-11 7:21 
A nice tip - maybe it should be posted under "tips and tricks" rather than articles, but still worth a 5
GeneralRe: My vote of 5 PinmemberIgor Merabishvili22-Jan-11 9:54 
GeneralRe: My vote of 5 PinmemberPhilippe Bouteleux24-Jan-11 2:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140718.1 | Last Updated 21 Jan 2011
Article Copyright 2011 by Igor Merabishvili
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid