Designing COM+ Applications with a Web Service Appeal
- Designing COM+ Applications with a Web Service Appeal
- Creating the COM+ Application
- Defining the Web Service
- Using the Web Service from .NET
One of the more interesting preconceptions that developers have about working with .NET is a perceived lack of compatibility with older applications. Some developers don't use .NET because they think it's going to be hard to get it to work with their existing applications.
Nothing could be further from the truth. Not only can you create COM applications with .NET, but you can also create COM+ applications, and then make those COM+ applications usable as Web Services. In short, you can write one .NET application and have it serve any of a number of environments, even those that appear on other platforms.
You can create COM or COM+ components with equal ease using .NET. In fact, the same component can serve both environments. All you need to do is create a Class Library project and add your code to it. You don't have to do anything weird to make your code accessible to VB6 or VC++ developers.
That said, you do need to add a few custom attributes and give your component a strong name to ensure it works properly. In addition, you need to provide an interface to ensure COM can actually see the methods.
All of these needs are relatively easy to address. Listing 1 shows the simple component used for this example.
Listing 1: Creating a Simple Class for Use with COM or COM+
namespace MyMathClass { [Guid("2D0B6B56-8572-4f25-8B13-E5CF81783E77")] [ComVisible(true)] public interface ISimpleMath { Int32 DoAdd(Int32 Input1, Int32 Input2); ... Other Methods ... } [Guid("33933BDB-794D-4d3e-963A-D6FBCEE068E4")] [ClassInterface(ClassInterfaceType.AutoDual)] public class SimpleMath : ServicedComponent, ISimpleMath { public SimpleMath() { } public Int32 DoAdd(Int32 Input1, Int32 Input2) { return Input1 + Input2; } ... Other Methods ... } }
Let's begin with the interface. You must create an interface for the class because COM and COM+ might not see the methods you expose otherwise. The interface must include two attributes: [Guid], which contains the Globally Unique Identifier (GUID) for the interface, and [ComVisible], which makes the interface visible to COM and COM+. You'll find that .NET automatically provides a GUID for you if you fail to include the [Guid] attribute, but you'll quickly find that this approach can leave your registry with tons of orphaned entries. Adding the [Guid] attribute is quick and easy, so it makes sense to use it to save time.
You might wonder where the mystery number for the [Guid] attribute comes from. Select the Tools | Create GUID command, and you'll see the Create GUID utility shown in Figure 1.
Figure
1. The Create GUID Utility.
Select option 4, as shown, and click Copy to place the new GUID on the clipboard. Paste the result into your code and remove the curly braces from either end of the GUID.
The class comes next. Notice that you must implement the interface in your class to create the required linkage. Like the interface, the class uses the [Guid] attribute, but not the [ComVisible] since the interface makes the methods public. The GUID you use for the class must be different from the one you used for the interface. The [ClassInterface] attribute contains one of the ClassInterfaceType
enumeration values. I recommend that you alway
use AutoDual, unless you have a good reason to choose one of the other options (such as making the component available to only VB6 or only VC++ developers).
Notice that this class inherits from the ServicedComponent class. This entry isn't too important when you want to use the component for COM or COM+ work, but Web services require it. If you don't include this entry, COM+ exports the basic interface information, but won't create the required method declarations; COM+ appears to create the Web service and even IIS seems to show that the Web service will work, but you won't be able to access the methods in the Web service.
You'll find the ServicedComponent
class in the System.EnterpriseServices
namespace. Theoretically, you can also
inherit from the Component class, which results in a less complex implementation, but it can also introduce problems in using the Web service in some cases (the export isn't as precise as it could be).
The code for the class isn't anything special. I just put something together for demonstration purposes. Any code you normally use for a .NET class will work in most cases. However, in special situations you have to use the InteropServices
namespace members, such as the Marshal
class to create a bridge between .NET and the Win32 environment.
Creating the code is a good start, but you must perform one additional task: give the component a strong name. To do that, open a command prompt and use the:
SN -k MyKey
command to create a key pair. This key pair signs the component to ensure no one can tamper with it. You add the strong name to the AssemblyInfo file using code, like this:
[assembly: AssemblyKeyFile(@"..\..\MyKey")]
Now you can compile the component. It's ready for use as either a COM or COM+ application.
Registering the Component
Unlike .NET applications, you must register COM and COM+ components for use. However, you don't use the normal RegSvr32 utility to perform this task with .NET components; instead, you use the RegAsm utility.
The RegAsm utility has more than a few command line switches, and I won't go into all of them in this article. However, you won't normally need to use all of those switches, especially when working with COM+. The example component creates MyMathClass.DLL
. To register this class in such a way that COM+ can use it, you'd type:
RegASM MyMathClass.dll /tlb:MyMathClass.TLB
at the command prompt and press Enter. RegAsm will create all of the required registry entries to use MyMathClass
. In addition, it creates a type library that you must have to add the component to COM+.
Before you make any changes to the code or recompile the component, make sure you unregister the component from the registry. Again, you use the RegAsm utility to perform this task. Here's the command line for this example:
RegASM MyMathClass.dll /unregister
Using RegAsm is good enough when you want to use COM+ alone. However, in this example, we also want to access the component as a Web service. To make the component usable at this level, you must also register it in the Global Assembly Cache (GAC) using the GACUtil utility. Like RegAsm, GACUtil includes a number of interesting switches you won't normally use. To register the example component, simply use this command:
GACUtil -i MyMathClass.dll
Removing the assembly from the GAC is equally easy. Simply use this command (notice that the DLL extension is omitted).
GACUtil -u MyMathClass