Shawn

Shawn Wildermuth

COM Objects and IDisposable?


I haven't dealt with a ton of COM interop up to this point in my .NET life.  I was surprised to find out that there is not a good story for deterministic deconstruction of COM objects...or maybe there is and I didn't see it.

What I've come up with is a bit of a hack to wrap a com object in a IDisposable wrapper so that I can use the using{...} syntax to determine Release() calls (not really destruction, but good enough for most cases).  The code looks like this:

/// 
/// Wraps an instance of a COM object in order to
/// provide deterministic deconstruction (or Release really).
/// 
public class DisposableCom : IDisposable
{
  /// 
  /// Public constructor to take a single COM object
  /// to call Release on upon Disposal.
  /// 
  /// 
  public DisposableCom(object comObject)
  {
    // Hack to allow us to Set a COM object that is initially null
    // but want only allow COM objects
    IntPtr typeInfo = Marshal.GetITypeInfoForType(comObject.GetType());
    if (typeInfo.Equals(null))
    {
      Marshal.Release(typeInfo);
      throw new ApplicationException("DisposableCom can only accept COM objects");
    }
    else
    {
      Marshal.Release(typeInfo);
    }

    _comObject = comObject;
  }

  ~DisposableCom()
  {
    ((IDisposable)(this)).Dispose();
  }

  private object _comObject = null;

  #region IDisposable Members
  void IDisposable.Dispose()
  {
    GC.SuppressFinalize(this);
    if (_comObject != null) Marshal.ReleaseComObject(_comObject);
  }
  #endregion
}

Can anyone find any holes in this idea?