Click here to Skip to main content
15,879,474 members
Articles / Programming Languages / C#

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

Rate me:
Please Sign up or sign in to vote.
4.91/5 (10 votes)
21 Jan 2011CPOL2 min read 56.7K   18   9
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:

VB
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:

C#
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:

C#
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:

C#
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)


Written By
Software Developer (Senior)
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Mahsa Hassankashi12-Mar-15 4:02
Mahsa Hassankashi12-Mar-15 4:02 
Questionaccess interface and methods Pin
abhibio4-Feb-13 1:43
abhibio4-Feb-13 1:43 
System.Type objType = System.Type.GetTypeFromProgID("MyProject.MyClass");
object comObject = System.Activator.CreateInstance(objType);

if comObject contains interface then how can we access the methods inside those interface ?
GeneralAnother option... Pin
Richard Deeming25-Jan-11 9:29
mveRichard Deeming25-Jan-11 9:29 
GeneralRe: Another option... Pin
Igor Merabishvili25-Jan-11 23:41
Igor Merabishvili25-Jan-11 23:41 
GeneralRe: Another option... Pin
Richard Deeming26-Jan-11 1:44
mveRichard Deeming26-Jan-11 1:44 
GeneralMy vote of 5 Pin
Yusuf21-Jan-11 11:05
Yusuf21-Jan-11 11:05 
GeneralMy vote of 5 Pin
Nemanja Trifunovic21-Jan-11 7:21
Nemanja Trifunovic21-Jan-11 7:21 
GeneralRe: My vote of 5 Pin
Igor Merabishvili22-Jan-11 9:54
Igor Merabishvili22-Jan-11 9:54 
GeneralRe: My vote of 5 Pin
Philippe Bouteleux24-Jan-11 2:45
Philippe Bouteleux24-Jan-11 2:45 

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

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