There is quite a bit of information posted on developing COM Callable Wrappers in .NET.  Below is some information that I've compiled after developing quite a few.

 Developing COM Callable Wrappers, all types exposed to COM should follow the guidelines presented in the following checklist:

 

-          Ensure AssembyVersionAttribute is set to a static value (i.e. 1.0.0.0 not 1.0.0.*)

-          Add System.Runtime.InteropServices namespace to files that have types exposed to COM.

o        This includes all of the Attributes necessary to create types exposed to COM.

-          An interface defined that exposes properties and methods for the type.

o        Creating this interface manually forces the developer to know that the interface has changed and can plan accordingly.  The alternative is to let the Type Library exporter automatically generate a interface for the type which can lead to accidentally deploying a type with a breaking change.

-          Creating a type (coclass) that implements the interface.

-          Decorate types with ClassInterfaceAttribute with a ClassInterfaceType.None value (i.e. [ClassInterface(ClassInterfaceType.None)] )

o        This attribute controls whether the Type Library Exporter (Tlbexp.exe) automatically generates a class interface for the attributed class.  Since the interface is defined manually and the coclass implements the interface, we are telling the Type Library Exporter that we have done the work ourselves. 

-          Decorate types and interfaces with ComVisibleAttribute with a true value (i.e. [ComVisible(true)] )

o        By default, all ComVisible is set to true.  Explicity setting these options signals which types and members are visible.

-          Decorate all structures, delegates, enumerations, fields, methods, and properties exposed to COM with ComVisibleAttribute with a true value; likewise, set all that are not visible to COM to false.

-          A parameter-less default constructor.

o        Needed to instantiate object via COM.  Parameterized constructors can be declared but cannot be used from COM.

 

The example class below shows a class that follows the guidance outlines in the above checklist.

 

using System;

using System.Reflection;

using System.Runtime.InteropServices;

 

[assembly: AssemblyVersion("1.0.0.0")]

 

namespace ComSample

{

      

 

       [ComVisible(true)]

       interface ICircle

       {

              double Radius {get; set;}

              double ComputeCircumference();

       }

 

  [ClassInterface(ClassInterfaceType.None),

       ComVisible(true)]

       public class Circle : ICircle

       {

              private double radius;

 

              public Circle()

              {

                     // parameterless constructor

              }

 

              [ComVisible(true)]

              public double Radius

              {

                     get{ return radius; }

                     set{ radius = value; }

              }

 

              [ComVisible(true)]

              public double ComputeCircumference()

              {

                           return radius * System.Math.PI;

              }

 

              [ComVisible(false)]

              public double WhatisPi()

              {

                           return System.Math.PI;

              }

       }

}

 

Figure 1. Sample class to be exposed via a CCW.

 

 

Each time the type is to be deployed, the .NET version must be increased.  Following versioning guidelines, each time the CCW is to be deployed, the major or minor version number should be increased.  This also allows the version to be clearly differentiated when the type is viewed.  Updating the version will produce a new CLSID (guid) associated with this type.  This is important step when deploying updated COM Callable Wrappers.

 

Any comments or reccomendations are welcome.