COM Interop:
Using an Existing COM Component to Create a Web Service
So, you've decided to take your now-legacy COM component into the world of Web Services using .NET. That's great! Now all you have to decide is whether you're going to rewrite it from scratch using VB.NET, C#, or managed C++ (mind-boggling), or, if it's VB6 to run it through the VB to VB.NET translation wizard (have you seen the garbage that produces?). Lovely.
But wait, those aren't your only options! How would you like to make ZERO changes to your code, and turn it into a Web Service anyway? Sounds great! But is it possible?
With COM/.NET Interoperability not only is it possible, it isn't even particularly tricky!
First Steps
To start with, we'll assume the following:
- You're running VS.NET (sorry, Notepad users -- you can still do it, it's just a bit more hands-on than I'm going to deal with right now!)
- Your COM component is already registered on your VS.NET machine.
- The component is installed in Component Services (there's a possible security problem if it's not)
I'm going to use a ficticious COM component, AstroFinder.dll, that supports exactly one class, SolarPlanets, with just one method , PlanetName (well, it's not really ficticious --- I wrote one for the purpose of the tutorial so I could get the screen shots that follow). This method takes an integer parameter with value 1 through 9, and returns the name of the planet (in English) as a string. We will attempt to expose this PlanetName method as a Web Service without making any changes to the COM component. This is a trivial exercise, but it will serve to illustrate the concept.
Create a New Web Service
First of all, open Visual Studio and select File | New | Project. Using your favorite language (I'll be using C# here), create a new ASP.NET Web Service. Before you click that OK button, you might want to change the project name from the default WebService1 (or whatever number it will be --- how many of these have you done already?), to something memorable like, in this case, Planets. Once VS has finished creating everything you'll need, I'm going to suggest that you dump the default Service1 in favor of a more meaningful name, in this case PlanetService. To delete Service1.asmx, right click on it and select Delete. To add PlanetService right-click the project, select Add | Add Web Service and click. Change the default name of the service, here to PlanetService.asmx, and click OK. At this point, the Solution Explorer would look about like this:

At this point we should right-click on our Web Service PlanetService and click on Set as Start Page.
Add a Reference to Your COM Component
Next step is to bring your COM component into the project. This is done simply by right-clicking the project again, and this time clicking on Add Reference, which brings you to the Add Reference dialog. Click on the COM tab, and Select your component from the list, then click OK (you could select multiple components here if you needed to).

The Component is Now Usable in the Project
| Once your component has been added, it is evident from the Solution Explorer that it is there, as seen here: |  |
| Note that if you happened to right-click on this Reference and select Properties, you'll find that it's name is Interop.AstroFinder. Remember that this whole concept is called "COM Interop". Interop is providing a wrapper here, which is why the name is the way it is. |
With AstroFinder as a reference in our project, we are now prepared to access all of its methods and properties.
And Now, Down to Coding...
With AstroFinder as a reference, we can use it in our coding, but if we want to avoid having to fully qualify it we would need to add a line to our source code where all the "using..." statements are. And that would be "using AstroFinder;" in C# (in VB.NET this would be "Imports AstroFinder"). If we didn't do this, we would have to refer to AstroFinder's methods by prefacing them with AstroFinder.
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using AstroFinder;
|
Now we will implement the PlanetName method. Note that I'm not going to use using AstroFinder; in my actual implementation, but that's only because I want the benefit of Intellisense below for illustration.
Building our Web Method
When you turn to the codebehind for the PlanetService (PlanetService.asmx.cs) you will find a commented out sample of a WebMethod labelled WEB SERVICE EXAMPLE. We're mainly going to follow this example, except that we're going to pass a parameter to our method.
Without further discussion, let's just look at what we're heading for:
[WebMethod]
public string PlanetName(short pNum)
{
AstroFinder.SolarPlanetsClass sp = new AstroFinder.SolarPlanetsClass();
return sp.get_PlanetName(pNum);
}
|
A minimalist example would have not included a parameter. But we're going beyond the minimum. Note that our PlanetName property in the COM object (which was written in VB6) takes a VB Integer, which is not a C# int. VB Integers are C# int32, or short. Interop will do most of the work, but not all. It wasn't mentioned, but PlanetName is defined in the COM component as a Property that takes an integer argument, in this instance. If it were a function, the code for the above would have been return sp.PlanetName(pNum). Interop handles the contradictions inherent in this nutty COM component by creating a function get_PlanetName for use in our WebMethod.
Here's pix of Visual Studio giving cues in Intellisense:
Testing Our New COM Interop-ed WebService
Remember I said to set PlanetService.asmx the Start Page? If you didn't do it then, do it now. It won't let you get away without it in any case. From the Debug menu item, select Start Without Debugging (because we don't want to debug it!) and away it goes. Assuming the Build worked without error, this is what we will see, in progression from upper left clockwise (putting 5 in the argument --- this should get us Jupiter and it does):
And Finally...
This really works. It has its idiosyncrasies (what doesn't?),
but the ability to use your pre-existing COM objects in .NET with little change will prove to be a big advantage for people and organizations that have a large investment in existing code. You don't have to have coded the components either --- you can Interop COM components that you didn't write.
I hope this tutorial has proven useful to you!
Happy .NETting!