Search This Blog

Monday, May 7, 2012

Developing a COM Class Collection using VB.NET COM Template

You can find the code here

In this post I will show you how to develop a COM Class Collection in VB.NET using the COM Template.
It is actually very easy, much easier that doing it manually. Here you can see the manual procedure.

The VB.NET ComClassAttribute, used by the COM Class template will generate for you automatically all the interface that you need to be exposed to COM.


If you define a Default indexed property, it will make it the default property for the COM Object, i.e. it will associate a DispId(0) to the Default indexed property.

In addition if you define a function

Function GetEnumerator() as System.Collection.IEnumerator
End Function

it will mark it as DispId(-4) to make it usable for the VB6/VBA For Each ... Next loop.

The COM Add-in will also create for you all the necessary GUID.

As you create a COM Class using the template, the template automatically will tick for you
1) Register for COM interop in Project Property/Compile/Register for COM Interop
2) It will make the assembly COM Visible. It will tick Project Property/Application/Assembly Infomatin/Make Assemby COM Visible.

The second part is usually a bad idea, this is because every type you include in the libray will be exported to COM. In case you do not provide some GUID for the type, each time you build the assembly the project will create some new ones for you, thus creating a dll hell.

The best thing you can do is to Untick Make Assembly COM Visible (and do it every time you use the COM template) and add a attribute ComVisible(true) on top of the class.
See an exampe here



Imports System.Collections
Imports System.Runtime.InteropServices



<ComClass(Employees.ClassId, Employees.InterfaceId, Employees.EventsId)> _
Public Class Employees
    Implements System.Collections.IEnumerable

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "4999e186-4ea8-4ce1-8da4-12db6f8600e8"
    Public Const InterfaceId As String = "43ecbe2f-714b-4dc9-a76c-85a84320b66d"
    Public Const EventsId As String = "069d7776-4953-44c2-bd17-0ff75cb5748b"#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Dim _SortedList As SortedList
    Public Sub New()
        MyBase.New()
        _SortedList = New SortedList
    End Sub

    Default Public Property Item(ByVal key As Object)
        Get
            Return _SortedList(key)
        End Get
        Set(ByVal value)
            _SortedList(key) = value

        End Set
    End Property

    Public ReadOnly Property Count()
        Get
            Return _SortedList.Count
        End Get
    End Property


    Public Sub Remove(ByVal key As Object)
        _SortedList.Remove(key)
    End Sub


    Public Sub Add(ByVal key As Object, ByVal value As Object)
        _SortedList.Add(key, value)
    End Sub


    Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        'Return _SortedList.GetEnumerator()
        Dim keys As ICollection = _SortedList.Keys
        Return CType(keys.GetEnumerator, IEnumerator)
    End FunctionEnd Class

No comments:

Post a Comment