Click here to Skip to main content
Licence CPOL
First Posted 21 Jan 2011
Views 9,129
Bookmarked 12 times

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

By | 21 Jan 2011 | Article
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)
Check24
Germany Germany

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralAnother option... PinmemberRichard Deeming9:29 25 Jan '11  
GeneralRe: Another option... PinmemberIgor Merabishvili23:41 25 Jan '11  
GeneralRe: Another option... PinmemberRichard Deeming1:44 26 Jan '11  
GeneralMy vote of 5 PinmemberYusuf11:05 21 Jan '11  
GeneralMy vote of 5 PinmemberNemanja Trifunovic7:21 21 Jan '11  
GeneralRe: My vote of 5 PinmemberIgor Merabishvili9:54 22 Jan '11  
GeneralRe: My vote of 5 PinmemberPhilippe Bouteleux2:45 24 Jan '11  

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.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 21 Jan 2011
Article Copyright 2011 by Igor Merabishvili
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid