Introduction

The ability to create COM components in .Net is very powerful.  You can harness the power of .Net and provide it to your legacy VB6 apps through COM Interop.

This reference identifies the specific procedure for creating a COM compliant component in C#.

Development

1.1 Imports

COM Interop functionality is contained within the System.Runtime.InteropServices namespace.

using System.Runtime.InteropServices;

1.2 Create Interfaces

You will need to create a public interface for each class that you want to expose to COM.  Your interfaces need to be marked with the InterfaceType and Guid attributes.

Each method or property that you define needs to be marked with a DispID attribute.  The ID’s that you assign in DispID need to be sequential (1, 2, 3, etc.).

[InterfaceType(ComInterfaceType.InterfaceIsDual),     Guid(“2B242F71-31C7-4dcc-A663-95A52CB1F7B8”)]

public interface IMyInterface

{

      [DispId(1)]

      void Method (string param1);

     

      [DispId(2)]

      String Name (get;)

}

1.3 Create Classes

Each class that you want to expose to COM needs to inherit the associated interface that you defined in step 1.2. Each class needs to be marked with the Guid, ClassInterface and ComSourceInterfaces attributes.

[Guid("AE307EE3-992E-4fdf-B52B-4C4FDFBFAC09"),       ClassInterface(ClassInterfaceType..None),       ComSourceInterfaces(typeof(IErrorLogger))]

public class MyClass : MyInterface

{          

      DBErrorLogger logger = null;

     

      public string Name()

      {

            Return “Daniel”;

      }

 

      public void MyMethod (string param1)

      {

            return “Hello World”;

      }

}

1.5 Enumerations

Enumerations (enums) are actually exposed to COM as classes.  Public enums need to be marked with a Guid attribute.

[Guid(“BA6DDF2B-C4BA-43ec-B6F4-FBA56F929587”]

public enum Level

{

      All = 0,

      High =1,

      Medium = 2,

      Low = 3

}

1.6 Register For COM Interop

 

1.7 Overloading

Overloading is NOT supported in COM.  Overloaded methods are exposed as a separate call. (i.e. LogError becomes LogError_2).

Deployment

1.1 Core Files & Dependencies

 

1.2 Regasm.exe

When deploying your dll to other machines, use RegAsm.exe.  It exports a type library (.tlb file) and registers it for COM. It’s okay if you overwrite an existing type library for the same assembly. The RegAsm.exe utility replaces the traditional RegSvr32.exe registration utility. RegAsm.exe can be found in:

[System]\Microsoft.NET\Framework\[Framework Version]

Run the utility from the command line as:

RegAsm.exe “C\Winnt\System32\ErrorLoggingCOMWrapper.dll” tlb:/ “C\Winnt\System32\ErrorLoggingCOMWrapper.tlb”

1.3 Referencing In VB/VBA

Your component should now be available from your references.

Attribute Reference

1.1 DispID (int dispId)

Uniquely identifies methods and properties of an interface/class to the COM Interop system.

1.2 GUID (string guid)

Each COM visible component (Classes, Interfaces, etc.) within your assembly is identified within the Interop system through a Guid.

1.3 ComSourceInterfaces

Identifies the event interfaces that the class exposes as COM connection points.  Use this attribute to specify the name of the interface associated with your class.

1.4 InterfaceType (COMInterfaceType interfaceType)

Using this attribute preserves binary compatibility.  Lets COM know whether your interface supports Late or Early Binding, or both.

COMInterfaceType

Member Name

Description

InterfaceIsDual

Indicates the interface is exposed to COM as a dual interface, which enables both early and late binding. InterfaceIsDual is the default value.

InterfaceIsIDispatch

Indicates an interface is exposed to COM as a dispinterface, which enables late binding only.

InterfaceIsIUnknown

Indicates an interface is exposed to COM as an IUnknown -derived interface, which enables only early binding.

1.5 ClassInterface(ClassInterfaceType classInterfaceType)

Lets COM know whether your class supports Late or Early Binding, or both.

ClassInterfaceType

Member Name

Description

AutoDispatch

Indicates that the class only supports late binding for COM clients. A dispinterface for the class is automatically exposed to COM clients on request. The type library produced by the type Type Library Exporter (Tlbexp.exe) does not contain type information for the dispinterface in order to prevent clients from caching the DISPIDs of the interface. The dispinterface does not exhibit the versioning problems described in ClassInterfaceAttribute because clients can only late bind to the interface. 

This is the default setting for ClassInterfaceAttribute.

AutoDual

Indicates that a dual class interface is automatically generated for the class and exposed to COM. Type information is produced for the class interface and published in the type library. Using AutoDual is strongly discouraged because of the versioning limitations described in ClassInterfaceAttribute.

None

Indicates that no class interface is generated for the class. If no interfaces are implemented explicitly, the class can only provide late bound access through the IDispatch interface. This is the recommended setting for ClassInterfaceAttribute. Using ClassInterfaceType.None is the only way to expose functionality through interfaces implemented explicitly by the class. 

The Type Library Exporter (Tlbexp.exe) exposes the first public, COM-visible interface implemented by the class as the default interface of the co-class. Beginning with the .NET Framework version 2.0, you can specify the default interface exposed to COM by using the ComDefaultInterfaceAttribute attribute. If the class implements no interfaces, the first public, COM-visible interface implemented by a base class becomes the default interface (starting with the most recently derived base class and working backward). Tlbexp.exe exposes _Object as the default interface if neither the class nor its base classes implement interfaces.