18.6 COM+ Support
The CLR also includes special plumbing and interop services
that allow CLR classes to be deployed as COM+ configured components.
This allows both CLR clients and classic COM clients to make use of
COM+ services for building scalable applications.
18.6.1 What Is COM+?
COM+ provides a set of services that are designed to help build
scalable distributed systems, such as distributed transaction
support, object pooling, Just-In-Time activation, synchronization,
role-based security, loosely coupled events, and others.
These services are provided by a runtime environment called the COM+
runtime, and are based on the idea of intercepting new COM object
creation and (possibly) method calls to layer in the additional
services as needed.
COM classes that use COM+ services are called Configured Components
because the exact set of services each COM class requires is
controlled and configured using declarative attributes that are
stored in a metadata repository called the COM+ Catalog.
The COM+ Catalog groups a set of configured components together into
something called an Application, which also has metadata settings
that control which process the COM components end up in when they are
created at runtime (the options here are Library and Server, where
Library components end up in the creator's process,
while Server components are hosted in a separate process), the
security principal the new process runs as, and other settings.
18.6.2 Using COM+ Services with CLR Classes
Naturally, CLR classes can also take advantage of COM+ services.
Although the underlying implementation of this is currently the
classic COM+ runtime, the mechanics of it are largely hidden from the
.NET programmer, who may choose to work almost entirely in terms of
normal CLR base classes, interfaces, and custom attributes.
The bulk of the functionality in .NET for using COM+ services is
exposed via the System.EnterpriseServices
namespace. The most important type in this namespace is the
ServicedComponent class, which is the base class
that all CLR classes must derive from if they wish to use COM+
services (i.e., if they want to be configured components).
There is a suite of custom attributes in this namespace that can
control almost all of the configuration settings that would otherwise
be stored in the COM+ Catalog. Examples of these attributes include
both assembly-level attributes which control the settings for the
entire COM+ application, the
ApplicationActivationAttributes, which controls
whether the CLR class is deployed in a COM+ Library or Server
application, and component-level attributes, which declare and
configure the COM+ services the CLR class wishes to be provided at
runtime. Examples of component-level custom attributes include the
TransactionAttribute (which specifies the COM+
transaction semantics for the class), the
JustInTimeActivationAttribute (which specifies
that the CLR class should have JITA semantics), the
SynchronizationAttribute (which controls the
synchronization behavior of methods), the
ObjectPoolingAttribute (which controls whether the
CLR class is pooled), and many, many others.
Although ServicedComponent serves as a special
base class which signals the .NET Framework that a class needs COM+
services, it also provides other capabilities. In classic COM+ work,
COM classes implement interfaces such as
IObjectConstruct and
IObjectControl to customize aspects of their
behavior. When using COM+ services in .NET, your classes can override
virtual methods provided by ServicedComponent that
mirror the functionality in IObjectConstruct and
IObjectControl, allowing a very natural,
.NET-centric way of accomplishing the same thing.
Other important classes in the
System.EnterpriseServices namespace include
ContextUtil and
SecurityCallContext. These classes provide static
methods that allow a CLR-configured component to access COM+ context.
This is used to control things like transaction status and to access
information such as the security role a caller is in.
Lastly, let's discuss deployment. Deploying
traditional COM+ applications requires one to configure the
component's COM+ Catalog settings. This is typically
done using either the COM+ Explorer (by hand, really only suitable
for toy applications) or using custom registration code. When
configuring CLR classes, there are two different approaches.
The first approach is using the RegSvcs.exe
command-line tool. This tool performs all the relevant COM Interop
and COM+ Catalog configuration, using both command-line options and
the custom attributes applied to your assembly and classes to control
the COM+ metadata. While this requires an extra step, arguably this
approach is the most powerful and flexible, resulting in
CLR-configured classes that can be used from both COM and .NET
clients.
Alternatively, the .NET COM+ integration is able to automatically
register classes that derive from
ServicedComponent in the COM+ catalog when they
are first instantiated. This has the advantage of not requiring any
additional setup, but also has several disadvantages, most notably
that the client code that indirectly causes the registration to occur
needs elevated privileges, and until the class is configured, it is
invisible to COM clients.
A simple C# configured class might look like this:
using System;
using System.EnterpriseServices;
[assembly:ApplicationName("MyCOMPlusApplication")]
[assembly:ApplicationActivation(ActivationOption.Server)]
[ObjectPooling(true), Transaction(TransactionOption.Required)]
public class MyConfiguredComponent : ServicedComponent {
public void DoDBWork( ) {
ContextUtil.SetAbort( );
// ... do database work...
ContextUtil.SetComplete( );
}
public override bool CanBePooled( ) {
return true;
}
}
|