So far, this chapter has established, through a couple of examples, that you can use your COM legacy components within any of your .NET-based applications. You don’t have to throw everything out quite yet. It’s now time to consider the opposite question: Can you run .NET components in the COM world?
Why on earth would you want to run .NET components in the COM world? It’s not immediately obvious, in fact, because migration to .NET would almost certainly be application-led in most cases, rather than component-led. However, it’s possible (just) to imagine a situation in which a particularly large application remains not based on .NET, while component development moves over to .NET. Let’s assume that that’s the case for the next section. The technology’s quite cool, anyway.
Let’s take a look at the .NET component. Here, you’ll implement an exact copy of the functionality created earlier with the MegaCalculator and MeanCalculator components, except you will use Visual Basic rather than VB6.
Begin by creating a Class Library project called MegaCalculator2. Here is the entire code of the interface for the class library:
Public Interface IMegaCalc Sub AddInput(ByVal InputValue As Double) Sub DoCalculation() Function GetResult() As Double Sub Reset() End Interface
Now create another Class Library project called MeanCalculator3. This will contain a class called MeanCalc that is going to implement the IMegaCalc interface, in a precise analog of the MeanCalc in your original VB6 MeanCalculator project. As before, you need to add a reference to MegaCalculator2 first, although this time it will be a true .NET Framework reference, and you’ll have to browse for it (see Figure 23-17).
Figure 23-17
This is what the code looks like:
Public Class MeanCalc Implements MegaCalculator2.IMegaCalc Dim mintValue As Integer Dim mdblValues() As Double Dim mdblMean As Double Public Sub AddInput(ByVal InputValue As Double) _ Implements MegaCalculator2.IMegaCalc.AddInput mintValue = mintValue + 1 ReDim Preserve mdblValues(mintValue) mdblValues(mintValue - 1) = InputValue End Sub Public Sub DoCalculation()_ Implements MegaCalculator2.IMegaCalc.DoCalculation Dim iValue As Integer mdblMean = 0 If (mintValue = 0) Then Exit Sub For iValue = 0 To mintValue - 1 Step 1 mdblMean = mdblMean + mdblValues(iValue) Next iValue mdblMean = mdblMean / iValue End Sub Public Function GetResult() As Double Implements _ MegaCalculator2.IMegaCalc.GetResult GetResult = mdblMean End Function Public Sub Reset() Implements MegaCalculator2.IMegaCalc.Reset mintValue = 0 End Sub Public Sub New() Reset() End Sub End Class
This is all quite similar to the VB6 version, apart from the way in which Implements is used. After this is all in place, build the assembly. Now we come to the interesting part: How do you register the resulting assembly so that a COM-enabled application can make use of it?
The tool provided with the .NET Framework SDK to register assemblies for use by COM is called RegAsm. This tool is very simple to use. If all you’re interested in is late binding, then you simply run it as presented in Figure 23-18.
Figure 23-18
The only challenge with RegAsm is finding the thing. It’s usually found lurking in C:\Windows\ Microsoft.NET\Framework\<version>, where <version> is the current .NET Framework version number. You might find it useful to add this to your path in the system environment. You can also use the Visual Studio command prompt to directly access this tool.
However, there’s probably even less reason for late binding to an exported .NET component than there is for early binding, so we’ll move on to look at early binding. For this, you need a type library, so add another parameter, /tlb (see Figure 23-19).
Figure 23-19
If you now take a look in the target directory, not only do you have the original MeanCalculator3 .dll, but you’ve also acquired a copy of the MegaCalculator2.dll and two type libraries: MeanCalculator3.tlb and MegaCalculator2.tlb. You need both of these, so it was good of RegAsm to provide them for you. You need the MegaCalculator2 type library for the same reason that .NET needed the MegaCalculator assembly: because it contains the definition of the IMegaCalc interface that MeanCalculator is using.
Turning the tables again, build a VB6 application to see whether this is really going to work. Copy the type libraries over to your pre-.NET machine (if that’s where VB6 is running) and create a Standard EXE project in VB6. Call this project CalcApp2. Within this project, you need to create references to the two new type libraries, so go to the References dialog box, browse to find them, and select them, as shown in Figure 23-20.
Figure 23-20
At this point, you have everything you need to create the application. Create it as you did for the Visual Basic CalcApp (see Figure 23-21). As before, the text boxes are txtInput and txtOutput, respectively, and the command buttons are btnAdd, btnCalculate, and btnReset. Here’s the code behind it:
Option Explicit Dim mobjCalc As MeanCalculator3.MeanCalc Dim mobjMega As MegaCalculator2.IMegaCalc Private Sub btnAdd_Click() mobjMega.AddInput (txtInput.Text) End Sub Private Sub btnCalculate_Click() mobjMega.DoCalculation txtOutput.Text = mobjMega.GetResult End Sub Private Sub btnReset_Click() mobjMega.Reset End Sub Private Sub Form_Load() Set mobjCalc = New MeanCalculator3.MeanCalc Set mobjMega = mobjCalc End Sub
Figure 23-21
Notice that this time you have to explicitly get hold of a reference to the interface IMegaCalc. The default interface of the component, MeanCalc, is entirely empty.
Make the executable via the File Make CalcApp2.exe menu item, and then move it back to your .NET machine (unless, of course, you’re already there). Run it up and see what happens (see Figure 23-22).
Figure 23-22
Well, that’s not quite what you expected. What’s happened here? In COM, the location of the DLL containing the component is available via the registry. In .NET, the assembly always has to be in either the current directory or the global assembly. All the registry is doing for you here is converting a COM reference to a .NET one; it’s not finding the .NET one for you.
But this is pretty easy to sort out. To resolve this problem, move the two assemblies, MegaCalculator3 and MeanCalculator2, to your current directory and try again (see Figure 23-23).
Figure 23-23
That’s better. You’ve established that in the unlikely event of having to run .NET from a COM-oriented application, Microsoft has provided you with the tools necessary to do the job.
In fact, Microsoft provides you with not one, but two alternative tools. The other one is TlbExp, which, as its name suggests, is the counterpart of TlbImp. Figure 23-24 shows how you can use TlbExp to achieve the same result as RegAsm in the previous section.
Figure 23-24