COM Registration Basics

COM+ Registration Basics

To create a COM+ component, you must first start a new class library project and add a reference to the System.EnterpriseServices.dll assembly. You can then derive custom classes from the System.EnterpriseServices.ServicedComponent class. Listing 9-1 shows a basic example.

Listing 9-1 A simple .NET serviced component
 Imports System.EnterpriseServices Public Class MyServicedClass     Inherits ServicedComponent          Public Function GetHello() As String         Return "Hello"     End Function End Class 

Behind the scenes, every serviced component is hosted by a COM+ application, which is really nothing more than a collection of serviced components along with COM+ configuration information. Every COM+ application is registered in the COM+ catalog. Using the administrative tools included with Windows, you can browse the COM+ catalog and modify the settings for various COM+ applications and their components.

With .NET, you have the freedom to place several serviced components into a single COM+ application or separate them into multiple COM+ applications. However, it's recommended that you use a one-to-one mapping between .NET assemblies and COM+ applications, as shown in Figure 9-2. Although it is technically possible to register the serviced components in a single assembly in different COM+ applications, this adds additional versioning and registration headaches.

Figure 9-2. Mapping classes to a COM+ application

graphics/f09dp02.jpg

To browse the COM+ catalog, select Component Services from the Administrative Tools section of Control Panel. Then burrow down to the COM+ Applications node, as shown in Figure 9-3. You'll see a list of all the currently registered COM+ applications and be able to configure them.

Figure 9-3. The Component Services console

graphics/f09dp03.jpg

Unfortunately, the serviced component shown earlier in Listing 9-1 isn't ready to use and won't appear in the Component Services utility. Furthermore, if a .NET client attempts to create this class, it will receive an error. Before putting a serviced component to work, you need to go through a few extra registration steps, as discussed in the next few sections.

Giving Your Assembly a Strong Name

Every serviced component needs a strong name that uniquely identifies your class and maps it to a component in a COM+ application. The process for generating a strong-named assembly is covered in detail in Chapter 2. Here's a quick overview of the steps you need to follow:

  1. Create a new class library project.

  2. Add MyServicedClass to the project, as shown earlier in Listing 9-1.

  3. If you don't already have a key pair, generate one using the sn.exe command-line utility.

  4. Add an <Assembly:AssemblyKeyFile> attribute to your class library project, identifying the file with the key pair.

  5. Compile the class library into an assembly.

After you've given your assembly a strong name, you're ready to register the component. You have two registration options: dynamic registration and manual registration.

Dynamic Registration

Dynamic registration, also known as "lazy registration," is a COM+ convenience that particularly shines when you test a serviced component. With dynamic registration, a serviced component is registered in the COM+ catalog as soon as it is instantiated by a .NET client.

If you create a simple client and add a reference to the test component shown earlier, for instance, you can instantiate MyServicedClass as you would any other .NET object:

 Dim MyServicedObject As New MyServicedClass() 

When you instantiate the object, a slight delay will occur. If you refresh the view in the Component Services utility, you'll see a new COM+ application with an application name that matches the assembly name used for your component (in this case, TestComponent). This COM+ application contains one configured class MyServicedClass as shown in Figure 9-4.

Figure 9-4. The dynamically configured MyServicedClass

graphics/f09dp04.jpg

If you examine the configured component in any detail, you'll notice that the GetHello method isn't listed. That's because COM is based on interfaces.

If you rewrite your class as shown in Listing 9-2, the members of IHello will appear. This will also get you on the path to exposing your serviced components to legacy COM applications (in other words, unmanaged applications that don't use .NET). This integration task is beyond the scope of this book, however. Creating a compatible .NET interface isn't difficult in principle, but it does require good knowledge of COM and the mapping between COM and .NET types. You are also exposed to the traditional COM versioning nightmares, including the problems that can occur if you create a new, incompatible interface under an existing interface GUID.

Listing 9-2 A .NET serviced component with an interface
 Public Interface IHello     Function GetHello() As String End Interface Public Class MyServicedClass     Inherits ServicedComponent     Implements IHello     Public Function GetHello() As String Implements IHello.GetHello         Return "Hello"     End Function End Class 

Dynamic registration might seem like the perfect solution to using COM+ in .NET, but it does suffer from a few quirks:

  • Registering a component in the COM+ catalog requires administrator privileges. If the component is instantiated for the first time in an account without these privileges (for example, the ASP.NET worker process that handles XML Web service requests), it will fail.

  • The component won't be reregistered unless you increase the version number. When you apply COM+ registration changes in your component code, they won't take effect because the component isn't reregistered. In these situations, it's often easiest just to delete the registration from the catalog manually and restart the application.

  • Dynamically registered serviced components can't be installed in the global assembly cache (GAC). This isn't a problem, just a common source of confusion.

For these reasons, it's often recommended that you use manual registration.

Manual Registration

To use manual registration, you use the regsvcs.exe command-line utility included with .NET. You need administrative rights to run this utility. Here's how you register TestComponent from the command line:

 regsvcs.exe TestComponent.dll 

The regsvcs.exe utility performs several tasks and informs you of any error it encounters on the way.

  1. It generates and registers a COM type library for the component, which might be useful if unmanaged clients need to use this component. In the preceding example, the type library has the name TestComponent.tlb.

  2. It searches the COM+ catalog for an application with a matching name (in this case, TestComponent). If it doesn't find one, it creates one. You can override the name choice by adding the /appname parameter or override it declaratively in the component code itself using <ApplicationNameAttribute> (as discussed shortly).

  3. It reads the metadata, determines the classes and interfaces to expose, and applies any configured COM+ settings. In the case of MyServicedClass, we haven't added any COM+ configuration attributes yet.

Here's the output you're likely to see:

 Microsoft (R) .NET Framework Services Installation Utility Copyright (C) Microsoft Corporation 1998-2001.  All rights reserved. Installed Assembly:        Assembly: C:\DistributedCode\COM+Component\bin\TestComponent.dll        Application: TestComponent        TypeLib: c:\DistributedCode\COM+Component\bin\TestComponent.tlb 

Alternatively, you can register a component programmatically by using the System.EnterpriseServices.RegistrationHelper class in a .NET application. This is a powerful but rarely used feature. In fact, the regsvcs utility uses the RegistrationHelper class behind the scenes.

It's also recommended that you install serviced component assemblies into the GAC. This isn't strictly necessary for library activation mode, although it is required for server activation. The key benefit of using the GAC is location transparency you won't need to worry about which version of an assembly is registered (and which version a given client is using).

COM+ and the Declarative Model

One of the core ideas in COM+ is that a component's behavior can be configured declaratively using attributes. In other words, if you want to create a component that uses transactions or object pooling in COM+, you don't code low-level API calls directly into your component code. Instead, you use attributes to declare to the COM+ runtime that your component needs certain services. The COM+ runtime then supplies these services transparently. These types of attributes (which are conceptually similar to but different from .NET attributes) can apply to an entire component, an individual class, or even a single method and can control everything from security to instance management.

In the past, these details were usually configured using the Component Services utility. You can try this out with the TestComponent application by right-clicking on the component itself or the contained MyServicedClass and then choosing Properties. Figure 9-5 shows some of the application-wide settings for TestComponent.

Figure 9-5. COM+ application settings

graphics/f09dp05.jpg

The COM+ catalog is still a part of the .NET world because it gives developers a flexible way to configure components in a production environment without recompiling. It also allows administrators to fine-tune components to match server hardware and software resources. For example, you might use object pooling to limit an object so it never exceeds the number of available licenses. If you install more licenses, however, you won't want to recompile the component. In this case, you can just tweak the settings by using the Component Services utility.

.NET extends the declarative COM+ model by allowing you to use special .NET attributes to mark up your code. These attributes replicate the settings you can configure using the Component Services utility. To configure the activation type for your COM+ application, for example, you can add an assembly-level attribute (typically to the AssemblyInfo.vb file):

 <Assembly: ApplicationActivation(ActivationOption.Library)> 

It's important to understand that this attribute is never directly executed as code. Instead, when your component is registered, all the COM+ attributes are used to configure the COM+ catalog settings. You can then override these settings by modifying them in the Component Services utility. Similarly, if you modify these attributes and recompile the component but you don't change the version number or reregister the application, the COM+ catalog settings won't be changed.

Most COM+ features are exposed through class-level or method-level attributes. However, you can use a few assembly-level attributes. You can specify the COM+ application that will be registered by using the <Assembly:ApplicationName> or <Assembly:ApplicationID> attribute. The former specifies the name of a COM+ application, and the latter specifies the globally unique identifier (GUID). Without the <Assembly:ApplicationID> attribute, .NET will generate a GUID automatically.

 <Assembly: ApplicationName("TestComponent")> 

You can also specify the activation type (server or library) using the <Assembly:ApplicationActivation> attribute.

 <Assembly: ApplicationActivation(ActivationOption.Library)> 

The default activation mode, if not specified, is library. In library activation mode, the components are executed in the client's process. Remember that in this case, the client process is the process that instantiates the serviced component, which will probably be a .NET Remoting component host or an XML Web service on the same machine. Using library activation will ensure the fastest possible communication.

If you use server application, all the components will be executed by dllhost.exe, the COM+ server process. You should be aware that in server activation mode, the component might not terminate when your application does, leading to "permission denied" errors when you attempt to rebuild the component and the .pdb debugging file. To put an end to this frustration, you must either wait until COM+ terminates the process (typically, after three minutes of inactivity) or shut it down manually using the Component Services utility. When using server activation, you also need to ensure that all method parameters and return values use serializable types.

COM+ Versioning

COM is extremely restrictive when it comes to versioning, largely because COM components are usually shared globally on a computer. Even a small change to a component's interface can cause existing applications to break.

When you create a serviced component, you will experience some of the hangover from the legacy of DLL Hell. By default, COM+ serviced components are registered in the Windows Registry using GUIDs to identify applications, components, and interfaces. When you register your serviced component, .NET generates a GUID automatically using a hash of the assembly's strong name and the version number. If you register your component again and the version number has changed, a new entry will be created in the COM+ catalog. Eventually, the clutter will build up and countless unneeded entries that reference old component versions will remain (as shown in Figure 9-6).

Figure 9-6. A COM+ versioning headache

graphics/f09dp06.jpg

To tackle this issue, you should lock down your assembly's version number while testing. Then modify the appropriate assembly attribute in the AssemblyInfo.vb file. For example:

 <Assembly: AssemblyVersion("1.3.0.0")> 

Of course, after you fix the version number, it's up to you to ensure that you increment the version number and generate a new set of GUIDs when it really is required namely, when you're ready to distribute a component that has a different interface. Once again, this will primarily be a consideration if you're in the unenviable position of interoperating with unmanaged clients. Another option is to lock down your GUIDs by specifying them in the code using the <Assembly:Guid> attribute for the assembly and the <Guid> attribute for each class or interface. In a complex component with multiple interfaces and classes, this approach requires significantly more code.

Using a COM+ Component

Now that you have a serviced component, how can you use it? You have three basic options:

  • DCOM

    This is the same approach you would use in Visual Basic 6.0. It's heartily discouraged, however, because DCOM is difficult to configure properly and inflexible in the enterprise (especially if your server is behind a firewall).

  • XML Web services

    In this case, your XML Web service effectively acts as a layer in between the COM+ component and the client. The XML Web service instantiates the COM+ component directly, just as it would with any other .NET assembly.

  • Remoting

    This is often the most flexible approach. Using a component host, you can expose a serviced component exactly as you would expose any other .NET object.

So far, we've explored how you can create and register a serviced component. The next few sections dive into the real details of COM+ programming and consider why you might want to use it.



Microsoft. NET Distributed Applications(c) Integrating XML Web Services and. NET Remoting
MicrosoftВ® .NET Distributed Applications: Integrating XML Web Services and .NET Remoting (Pro-Developer)
ISBN: 0735619336
EAN: 2147483647
Year: 2005
Pages: 174

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net