3

My application needs to interact with a COM object that, for reasons irrelevant to this post, cannot be added to my project as a reference. I thought the C# dynamic keyword would be the perfect solution, but am running into RuntimeBinderException when trying to access documented members that I believe to be accurate.

For completeness, I am working against the HP Application Lifecycle Management (ALM) OTA COM library for ALM 12.20, although I am going to generalize what I think might be happening without referring to those objects directly.

Consider the following code structure of the COM objects (in C# syntax for readability)

public interface InterfaceA
{
    string PropertyA { get; }
}

public interface InterfaceB
{
    string PropertyB { get; }
}

public class ClassA : InterfaceA
{
    public string PropertyA { get; }
}

public class ClassB : ClassA, InterfaceB
{
    public string PropertyB { get; }
}

This is this basic signature of a method on an object that returns the object I need to use:

public InterfaceA ReturnObject()
{
    // Returns object that implements InterfaceA and also InterfaceB
    var myClassB = new ClassB();
    return myClassB;
}

And the following shows the basics of how I consume those objects (disregard specific syntax)

dynamic dynamicClassB = someOtherDynamicObject.ReturnObject();
Debug.WriteLine(dynamicClassB.PropertyA + "; this works");
Debug.WriteLine(dynamicClassB.PropertyB + "; this throws RuntimeBinderException");

I did not author this COM library, so I'm not entirely certain of the object and interface relationships, but I believe the pseudo-code accurately reflects what is happening.

Normally, you'd have to explicitly cast ClassA to ClassB in order to access the property of the the ClassB object, but my understanding of the C# dynamic keyword is that this should not be necessary and may not even be possible. At run-time, it's possible that the dynamic object is being resolved as an instance of ClassA instead of ClassB, perhaps due to the signature of the method that returned the object (since it defined ClassA as the return type).

I've used dynamic successfully for many of the COM objects in this library, but am specifically having trouble with a few of the methods/properties on an instance of a class that is like ClassB in this example.

Thoughts/ideas/workarounds are appreciated. The only thing I can't do is directly reference the COM DLL in my project. Thanks in advance.

HgCoder
  • 1,243
  • 9
  • 14
  • The odds that you accurately modeled the way this COM server works are zero. COM servers never expose objects, only interfaces. Obtaining a property that belongs to a different interface requires a cast. That's not going to fly when you can't get the type library converted, you don't know what to cast to. VS is very picky about type libraries you add as a reference, it gets grumpy about any minor problem and doesn't tell you why. Instead run Tlbimp.exe from the Visual Studio Command Prompt to convert the type library. You'll get some warnings, you can probably ignore them. – Hans Passant Sep 27 '15 at 17:00
  • @Hans, thank you for the response. Unfortunately I can't use Tlbimp.exe for my project (long story). I have adjusted my original sample code to more accurately reflect that COM returns interfaces. The issue appears to be I have an instance of an object (of type ClassB) that must be resolving via the dynamic keyword to InterfaceA. I need to use methods/properties of InterfaceB. Normally I'd cast this to InterfaceB, but the use of 'dynamic' is throwing me off. If dynamic doesn't resolve the right type, and I just out of luck? – HgCoder Sep 27 '15 at 18:33

1 Answers1

4

For my scenario, it turns out the documentation I had was inaccurate and that the RuntimeBinderException was valid since the requested member was not present on the COM object as thought.

HgCoder
  • 1,243
  • 9
  • 14