Recipe 17.2 Call a .NET Component Containing a Parameterized Constructor

17.2.1 Problem

Attempting to call a .NET class containing a parameterized constructor generates the compile error "Invalid use of New keyword". Is there some sort of workaround so that I can call a .NET class containing a parameterized constructor?

17.2.2 Solution

To see the problem, you will need to follow these steps:

  1. Start a Visual Studio .NET command prompt and run the RegAsm utility program on the Geometry.dll file found in the Geometry\bin folder of this chapter's sample files using the following syntax (see topic 17.1 for more details on the Visual Studio .NET command prompt and running the RegAsm utility):

    regasm Geometry.dll /tlb: Geometry.tlb /codebase

    RegAsm will display a warning about this being an unsigned assembly but you can safely ignore the warning.

  2. Load the 17-02.MDB database and open the frmCircleDirect form in Design view.

  3. From the VBA IDE, select Tools References. At the References dialog, select the Geometry component.

  4. Close and save the form.

  5. Open frmCircleDirect in form view. Enter a numeric value into the Radius textbox and click the Calculate button. Access should respond with the error shown in Figure 17-3.

Figure 17-3. This compile error is triggered when you attempt to instantiate a .NET class containing a parameterized constructor
figs/acb2_1703.gif
  1. Click OK. Select Run Reset and close the form.

The Circle class is shown here:

    Public Class Circle
        ' NOTE: This class contains a 
        ' parameterized constructor which
        ' prevents it from being called
        ' by a COM program. 

        Private RadiusVal As Double

        Public Sub New(ByVal Radius As Double)
            ' This constructor takes a parameter
            RadiusVal = Radius
        End Sub

        Public Property Radius( ) As Double
            Get
                Return RadiusVal
            End Get
            Set(ByVal Value As Double)
                RadiusVal = Value
            End Set
        End Property

        Public Function Area( ) As Double
            Return Radius ^ 2 * System.Math.PI
        End Function

        Public Function Circumference( ) As Double
            Return 2 * Radius * System.Math.PI
        End Function
    End Class

This class is inaccessible from Access because its constructor (the New subroutine) contains a parameter. The trick to being able to call the inaccessible class from Access is to create a helper class that you can use to call the unavailable class. To create a helper class that you can use to call the Circle class, follow these steps:

  1. Exit Access completely. This is necessary because otherwise Access may place a lock on the existing Geometry.tlb type library.

  2. Start Visual Studio .NET and load the Geometry project.

  3. Open Geometry.vb and add the following class after the Circle class's End Class statement:

    Public Class CircleCOM
        Inherits Circle
    
        Sub New( )
            ' Call base class' constructor
            ' with dummy radius value.
            MyBase.New(1)
        End Sub
    
    End Class

    Notice that the new class, CircleCOM, inherits from the original inaccessible Circle class.

  4. Compile the project by selecting Build Build Solution.

  5. Start a Visual Studio .NET command prompt and run the RegAsm utility program on the updated Geometry.dll file found in the Visual Studio Projects\Geometry\bin folder of this chapter's sample files using the following syntax (see topic 17.1 for more details on running the RegAsm utility):

    regasm Geometry.dll /tlb: Geometry.tlb /codebase

    RegAsm will display a warning about this being an unsigned assembly but you can safely ignore the warning.

  6. Restart Access and load the 17-02.MDB database. Open the frmCircleUsingHelper form in design view.

  7. From the VBA IDE, select Tools References. Verify that the Geometry component is selected.

  8. Note the source code behind the Calculate command button:

    Private Sub cmdCalculate_Click( )
        Dim cirCOM As Geometry.CircleCOM
        Set cirCOM = New Geometry.CircleCOM
        
        cirCOM.Radius = txtRadius
    
        lblMsg.Caption = "Area of circle: " & cirCOM.Area( )
    End Sub
  9. Close and save the form.

  10. Open frmCircleUsingHelper in form view. Enter a numeric value into the Radius textbox and click the Calculate button. Access should display the result as shown in Figure 17-4.

Figure 17-4. frmCircleUsingHelper instantiates a helper class, CircleCOM, which calls the inaccessible class, Circle
figs/acb2_1704.gif

17.2.3 Discussion

The helper class could have been constructed in a number of ways. Although we chose to use a derived class, the helper class could also have been independent of the original class. The helper class could live within the same component or in a separate component. In this example, we chose to make the helper class a derived class that lives in the same component as the inaccessible class.

In this example, you were able to use the CircleCOM class to call the Circle class. In instantiating the Circle class, CircleCOM passed a dummy radius value to the constructor. Because Circle also included a Radius property, you were able to specify the radius value prior to calling the Area method. There may be some classes where properties that duplicate the constructor parameters are not available. In these cases, it may be difficult if not impossible to create a helper class that is able to instantiate the inaccessible class for you.

Many of the built-in classes of the .NET Framework contain parameterized constructors. This means that you will need to create a lot of helper classes in order to work with these classes.