Search code examples
c#comwrapper

How can I use types from a wrapped resource outside of the wrapper?


I'm trying to wrap a COM API so that others can use my wrapper without knowing anything about the wrapped API. However, I've hit a problem trying to use some of the items from the COM API.

Let's say the COM API has a method that returns an object defined within the API.

IComChildObject IComObject.GetChildObject()

If I have a reference to the dll that defines the COM API, I can easily use this as follows...

IComChildObject childObject = myComObjectInstance.GetChildObject();

The problem I have, is that I need to be able to work with the IComChildObject through the wrapper class, without referencing the COM API dll.

I tried to create an interface in my wrapper, that would accomplish this. So inside my wrapper project, I have an interface like this.

public interface ILocalChildObject : IComChildObject{}

Then I added a property to my wrapper, that I thought would allow my external code to use the IComChildObject.

public class ComWrapper
{
    IComObject comObject;

    public ILocalChildObject ComChildObject { get { return comObject.GetChildObject() as ILocalChildObject;}}
}

When I run the following code from my external code, the ChildObject is null

ILocalChildObject ChildObject = myComWrapper.ComChildObject;

I'm obviously doing something wrong, but I'm in over my head on this and don't even know what to search Google for.

Maybe it's not clear what I'm trying to do, or maybe I'm trying to do something strange here. I want to create a wrapper class library in such a way, that the code that uses it doesn't have to know anything about the wrapped library. I've done okay so far, up until the point where I need to use objects from the wrapped library in the external code. I could easily resolve this by referencing the wrapped library in my external project, but I'd like to avoid doing that.

Basically, I just need a way to use the IComChildObject in my external code, without adding a reference to the COM API dll.

Any help would be greatly appreciated,


Solution

  • Another way to handle this, as Hans Passant points out, is to wrap the COM API object in a class. Then you can access the properties within the object through the new object. The only downside to this approach is there's a lot of typing, as you have to recreate any properties or methods that you want to access in the COM API object.

    In the wrapper project, you'll create a class that will contain the object returned from the API. This class will also have properties and methods, that allow a user to manipulate the API object through the class.

    public class LocalChildObject
    {
        internal IComChildObject ComChildObject;
        
        public string ChildObjectProperty { get { reutrn ComChildObject.ChildObjectProperty; } set { ComChildObject.ChildObjectProperty = value ;}}
        
        public LocalChildObject(IComChildObject ComChildObject)
        {
            this.ComChildObject = ComChildObject;
        }
    }
    

    In this example, ComChildObject is the object returned from the API. Then there's a property in the class ChildObjectProperty, which allows you to get or set the ChildObjectProperty of the ComChildObject.

    Then in my main wrapper class, I can have a property that returns this new object (which contains the API COM object).

    public class Wrapper
    {
        public LocalChildObject GetLocalChildObject { get { return new LocalChildObject(ComObject.GetChildComObject());}}
    }
    

    Then in the external code I can make changes to the object through the new wrapper object

    LocalChildObject localObject = myWrapperInstance.GetLocalChildObject;
    localObject.ChildObjectProperty = "A new string";
    

    This method requires recreating all the properties and methods that you want to expose through the wrapper, however, it does allow the user using the wrapper to use IntelliSense.