| Printable Version
XP, Component Services
and .NET
By John Godel
Introduction
/ Component Services
First of all, COM+ does
revolutionize COM; it is not only a superior new version of the COM programming
model it is also a new platform to design and develop components. In addition,
COM+ Services in XP does have some differences from Windows 2000; also XP and
COM+ 1.5 offer a richer set of services than was available in COM+ 1.0. This
article will describe the basic component services on the XP.
COM+ can be used to
implement mission-critical, enterprise-class, distributed applications based on
the Microsoft Windows XP. In the last release, COM+ adds new features that are
designed to boost the complete scalability, availability, and manageability of
COM+ applications for both developers and system administrators. To make it
easier to configure and deploy these new features enhanced documentation and new
reference topics have been added to the Platform SDK documentation. Furthermore,
Help topics have been updated in the Component Services administrative tool.
Microsoft Windows XP
emerging with it the new version of COM+ that is called COM+ 1.5. This article
describes the new features and capabilities in this new release. Microsoft has
superior COM+ usability in many ways, and they have addressed a numerous the on
hand pitfalls of COM+ 1.0. Microsoft also added new features to existing
services. In addition it stands on the base for integration with Microsoft .NET
services. Certainly, that COM+ 1.5 is fully backward compatible with COM+ 1.0
components and applications and that gives you the ability to use COM 1.0
components, which you develop them
before.
You will need
to use COM+ for several of reasons while you design and develop enterprise
software. If you are a system administrator, you can install, deploy and
configure COM+ applications and their components. If you are an application
programmer, you can write components and integrate them as applications. If you
are a tools vendor, you can develop or modify tools to more functional in the
COM+ environment.
Why Do
We Need Component Services?
COM+ brings an experience to
design and developing enterprise applications and making life trouble-free for
software designer and developers. Users can now concentrate on developing
business sense with simplicity, while being secured from the basic aspects of
enterprise application development from beginning to end the use of COM+
components.
Once
more, COM+ designed to make it simple to design and develop enterprise-class
distributed applications. However, we should decide about what is really an
enterprise-class mean. An enterprise-class distributed application is timely
implementation and correct application processes also doing critical operation
of some business. Additionally, this type application can use with many
different user types such as clients, employers, operators etc. All
enterprise-class application should be relational with internet/intranet,
multi-tier networking with security capabilities. As well, one of Microsoft's
goals in developing COM+ has been to offer companies the benefits of multi-tier
applications while hiding as much of the inherent complexity as possible. More
than the last decade, Microsoft has made many advances in creating this
infrastructure for distributed applications. Opposing to common opinion, the
.NET Framework does not replace COM+. You still need COM+ services—such as
distributed transactions, object pooling, Just-In-Time Activation (JITA),
synchronization, and queued components—to build enterprise-class,
distributed applications on the Windows platform. In this article, you will
learn how to create and deploy a serviced component, which is Microsoft's name
for a .NET component that uses the COM+ services.
What
is a Component Services?
You must recognize component
services are COM+ in Microsoft XP and 2000 Operating Systems; it is the new step
in the evolution of the Microsoft Component Object Model with Microsoft
Transaction Server (MTS). COM+ handles many of the resource management
responsibilities you until that time had to program yourself, such as thread
security and allocation. It automatically makes your applications more scalable
by providing thread pooling, object pooling, and just-in-time object activation.
COM+ also protects the integrity of your data by providing transaction support,
even if a transaction spans multiple databases over a
network.
Like
applications, components as a part of application need a runtime service to
work. Briefly, the services, which support COM and .NET components under Windows
2000 and XP, are COM+ Component Services. COM+ is the fundamental COM and a set
of additional services such as Transactions, Queued Components (QC), Security,
Loosely Coupled Events (LCE), Just-In-Time Activation (JITA), Basic Interception
Services, Object Pooling, Deployment, and Administration. The COM enhancements
include improvements in both threading and security, along with the introduction
of Asynchronous COM. The new services include synchronization, object pooling,
and queued components, as well as a new distributed application administration
and packaging service (Component Services). For those usual with COM
programming, the COM+ improvements are significant. COM+ implements a new
threading model called neutral apartment threading, which allows a component to
have serialized access but also execute on any thread. In addition to the
threading model, COM+ provides role-based security, asynchronous object
execution, and a new built-in moniker that represents a reference to an object
instance running on an out-of-process server.
Tools
to Create a Component Service
Visual Studio .NET has a
magnificent tool set for create a component service in XP. Visual Studio .NET
and the individual tools and languages it contains are the foundation for
building Windows-based components and applications, creating scripts, developing
Web sites and applications, and managing source code. Most important ones are C#
and VisualBasic.NET. In addition, Visual C++ 7 is an excellent tool for create a
component service. Recall that COM+ is a binary standard for building and
integrating software components. All languages are tools, which you used them
for create component service in .NET
environment. When Microsoft developed
COM+, it was intended and
targeted mainly for Microsoft Visual C++ and Visual Basic developers.
Furthermore, Microsoft designed COM+ to manage and deploy applications. In
addition to that, in .NET environment you can use some other programming
languages and tools such as COBOL, Perl, J#, C# to develop a component services.
Visual Studio.NET supports many languages additional to its official languages
C#, C++ and VisualBasic.NET. Our main tools will be Visual Studio.NET and Visual
C++ 7.0 compiler in this article.
What
is new in COM+ with XP?
COM+ that offered by XP
improve new features that are designed to increase the complete scalability,
availability, and manageability of COM+ applications for both designers and
developers. To make it easier and functional to design, develop and deploy these
new features, enhanced documentation and new reference topics have been
supplemented to the Platform SDK documentation. In addition, Help topics have
been reorganized and restructured in the Component Services tools.
There are several
new technologies in COM+ with XP such as COM+ Partitions, Application Recycling,
Application Pooling, Moving and Copying COM Components, Configurable Isolation
Levels, Running COM+ Applications as NT Services, Creating Private Components,
Low-Memory Activation Gates, Pausing and Disabling Applications, and Process
Dumping.
Make
Your Components Stronger and More Efficient with Windows XP
With XP, COM+ 1.5 provides
many powerful and useful run-time services, which saves time while you develop
enterprise-class software. Windows XP replaces Windows 2000 and Windows Me. XP
derives the power of Windows 2000 and usability of Windows Me and possesses more
futures such as COM+. Windows XP is based on the Windows 2000 architecture and
inherits that operating system's power and performance. Windows XP also inherits
and improves the new features of the Windows Me operating system: such as system
restore, Windows Media Player, Windows image acquisition, and many more. Windows
XP brings a strong base, to maintain and develop assemblies and isolated
applications.
Moving
and Copying Components
Under COM+ services you will
have the authority to move and copy your components which means that you can
configure a single physical implementation of a component several times. With
having the power of moving and copying components you had component reuse at a
binary level before the source code level. And that means a reduced amount of
code, decreased development costs, and earlier marketing. Moreover, a component
can be moved from one COM+ application to another. In effect, once you move a
component it is removed from the previous COM+ application and installed it in
the new COM+ application. To move a component from one COM+ application to
another, first, in the details pane of the Component Services administrative
tool, right-click the component that you want to move and then click Move and
than in the this dialog box, select the destination COM+ application to which
you want the component to be moved. To finish this process click OK.
In addition, you can
copy a component from one COM+ application to another one. Once you copy a
component to another COM+ application, you can configure this component like a
different component than the original component. When you need to copy a
component from one COM+ application to another one, first, you may right-click
the component that you want to copy in the details pane of the Component
Services administrative tool. In addition, after that click Copy and than in the
Copy Component dialog box, during the ‘Please select a Destination’
pane, select the COM+ application to which the component will copied. Write the
new ProgID for the copied component. Insert the new CLSID for the copied
component. COM+ displays an automatically generated CLSID. In most cases, this
will be sufficient to uniquely identify the copied component. Enter a new CLSID
only if you want to change the one provided by COM+ and than click OK and
finish.
Legacy
applications and Components
The most significant advantage
of having your legacy components as part of your COM+ 1.5 application is
straightforward deployment. If you need to export a COM+ application, remember
that its MSI file contains the legacy components and their settings. After that,
you need to install the MSI file on another computer. At this point, the Windows
Installer registers the components, therefore you will not need to write a
separate installation program for each project and you will not have the
particular problems of the
installation.I would
like to drive your attention to that the COM+ 1.5 has the enhanced generation of
Explorer user interface. As you recall, under COM+ 1.0, the only technique to
tell the activation type of a COM+ application was to bring up its Activation
tab and examine it. The COM+ 1.5 Explorer allocates different icons to different
application types. This will give us the chance to figure out the type of the
application, server, library, proxy, or service, just by viewing icons from
Explorer’s window. You can find Running Processes folder, which contains
all the currently executing applications, providing easy runtime administration
under My Computer. This folder is very important to watch applications if any
runtime problem
occurs. Figure-1
Legacy Component Properties
PageAs you may
recall the COM+ 1.0 Explorer only gives you the ability to handle and
administrate configured components. If your software is built entirely on
configured components, then that may not be a problem for you. Unfortunately,
often enterprise class software needs legacy and some other types of components.
Developers use other tools in addition to the COM+ Explorer to manage legacy
components in a diverse environment. The best examples to these tools are
OLEView, Visual Studio, or custom tools. Programmers need to handle two types of
deployment approaches. First of them uses exported COM+ applications (MSI files)
and the second may include anything that they need to do to install their
specific legacy components. Fortunately, COM+ 1.5 supports all those for legacy
applications and components. This allows you to deal with every characteristic
of your legacy applications and
components.You will find
a new folder called DCOM Config under My Computer in the COM+ 1.5 Explorer. This
important folder is closely related to the COM+ Applications folder also
includes all the registered COM local servers on your Computer. All of the local
servers are called a legacy application and you cannot expand a legacy
application down to the component, interface, or method level as you do in COM+
application, when we focus on COM+ 1.5 we see that a legacy application is
concrete. As a result, this folder gives you the ability to handle and
administrate both your COM+ applications and your legacy local servers. In
addition, at this point you will not need the utilities, which you used in
previous version of
COM+.If you select
properties from legacy application’s popup context menu, you can handle
and administrate all the characteristic specifications. Another important issue
for a developer is security. For a developer the other Tabs are not very
important. On the other hand, Security tab allows you to configure access,
launch, and change permissions for each user. When you need your COM+
application to use a legacy component, you can use COM+ 1.5 Explorer and it will
allow you to handle and administrate those. When you develop a COM+ 1.5
application that has legacy components than it will have a folder named Legacy
Components. If you like to add a legacy component into this folder just select
New from the context menu. One of the most important advantages of COM+ 1.5
Explorer is the Import Wizard, which allows you to select legacy components and
add them to your COM+1.5 applications. I would like to remind you that legacy
components can be added only in the same application.
If you need to see
registry entry or a legacy component, you can use properties page. However, I
need to bring your attention to registry entries because you can only change the
values of settings, which do not conflict with registry settings in the
component itself. All those save the developer’s time and make the
application effective and bug-free. If you are a developer that uses Windows XP
than you will have all this functionality of new COM+ 1.5 Explorer and Legacy
Components.
Queued
Components
Queued Components allow you to
create components that can execute immediately if the client and server are
connected. They provide an easy way to invoke and execute components
asynchronously. If the client and server are not connected, the component can
hold execution until a connection is made. By using method calls similar to
those calls used in component development, withdrawing the need for a
comprehensive knowledge of marshaling Queued Components supports the developer.
You can use Queued Components to build COM+ applications that are not
time-related. Using messaging and queuing helps your applications handle the
disconnected client case; it can also increase reliability and
scalability.
Queued
components have enormous implications for enterprise application development,
particularly for disconnected client applications and those running on personal
digital assistants. If a server component is not available, Windows will queue
execution on the client computer. It's a whole new way of implementing
components, in which you can no longer count on a component being available in
memory at the time of the call, either on the local or a remote computer. There
are some remarkable possibilities with this feature, but they require completely
rethinking application design. Queued Components, a key feature of COM+ and
based on Microsoft Message Queuing Services (MSMQ), provides an easy way to
invoke and execute components asynchronously. Processing can occur without
taking into account the availability or accessibility of either the sender or
receiver. A small shopping network is a model of the type of application that
might advantage from asynchronous processing. In this asynchronous, disconnected
scenario where viewers’ phone in to several operators, orders are taken en
masse and are then queued for later retrieval and processing by the
server.
When
designing new applications, developers must consider the implication of coding
components for real-time (or synchronous) processing against queued (or
asynchronous) processing. Eventually, the choice depends on the requirements of
the specific application and determining which method better serves the
underlying business logic of the application. Using queued processing offers
advantages for certain applications, while writing an application using
real-time, synchronous processing could be the best choice for another
application. As an instruction, ‘queued processing’ offers the
subsequent advantages over real-time processing:
- Component Availability
- Component Lifetime
- Disconnected Application
- Message Reliability
- Server Scheduling
Better
Queuing Foundation
Before XP and COM + 1.5 under
COM+ 1.0 Queued, components needed the existence of a domain controller to give
authentication for the queued request. This means, if you do not have a domain
controller, you have to shut down COM+ 1.0 application authentication. COM+ 1.5
gives an authority to improved configurable security verify for queued request
through sorting them out from normal synchronous calls. The application Queuing
tab now lets you configure authentication for queued calls explicitly.
Improved queuing
support helps you to manage the maximum number of simultaneous player components
the application can have. As every player component is created on a separate
thread, there is unsurpassed operating cost linked with generating and
maintaining a player component. In deep situations, your application may grind
to a stop the progress if the number of matched player components is too large.
The Queuing tab also lets you to manipulate Microsoft Message Queuing (MSMQ)
domain controller authentication once the application is configured to use
authentication for synchronous calls. Never authenticate queued calls into this
application. Choosing this option lets you to openly use queued components
without a domain controller. Continuously, authenticate incoming queued calls,
not considering of the application authentication
setting.
When you put
a limit to the number of player components and that limit is reached, the
listener does not generate new player components. Preferably, queued calls
remain in the application queue, allowing calls in progress to execute and
complete. The limit is also good for load balancing purposes, and can be used in
concurrence with application pooling.
Private
Components and Assemblies
Private components and
assemblies are the other new and very important features that are brought by
Windows XP and COM+1.5. Private component is a component that is to be accessed
only by other components in the same application, same as that a private
assembly is an assembly which only visible to one application. Private
components are required in approximately all enterprise class COM+ projects.
Similar to that most
of the .NET applications need minimum one private assembly to isolate the
application from changes made to the system by other applications. Also, if you
do not want to give permission to a client for accessing to a component and
assembly, you need to deploy them as private. Please note, a private assembly
can include more than one private component. In COM1.5 each component has a
select box under the activation tab to mark it private or not private.
Furthermore, you can mark a component programmatically private.
Disabling
Components
Components can be disabled on
a case-by-case basis from the component’s popup context menu by using
Disabled option. After disabling a component, you may see a red square on
component’s icon. If you see this red square on any component’s
icon, which means before using this component you must enable it. Because, all
software from client computer, which attempt to create a disabled component,
will be failed and they will have a message that the component has been
disabled.
If you need
to disable any type component including the legacy components in a COM+1.5
applications, you can use this disabling method. When you disable a component
this will only influence activation requests and, the other existing
object’s references will not be affected. Finally, when you need to enable
a component just use the context menu and enable it.
Disabling
Application
You can disable applications
just as you can disable components. When you disable an application, all client
attempts to create components from that application will fail, with the
following message returned: “The component has been disabled." To disable
an application, display its popup context menu and select Disable. When an
application is disabled, a red square also is displayed on its icon in the COM+
1.5 Explorer. If you need to enable a disabled application, bring up the context
menu again and select
Enable.
Disabling an
application has two beneficial points. The first one is that if you need to
upgrade or change fundamental structure of the software in a live server
computer there are two choices for you: shut down the application or disable the
application. Of course disabling the application will be better than shutting
down the application. Because, this will allow the existing client to finish its
job, also, it will hold the existing references to this application. And the
second beneficial point is that in the testing and developing phase you need to
verify the failure of the client’s attempt to this application and
disabling an application will provide you this opportunity.
You should keep in
mind that before deploying your application you must test all those kind of
failure attempts to your application. Because, after releasing your enterprise
class application this kind of failure will cause major technical problems.
After all, disabling application is a very important tool for you. It is
important that, you can not disable Legacy applications but you can disable a
COM+ 1.5 application. It is interesting that a client computer that already has
a reference to a COM+ object is not influenced by the fact that the application
has been disabled. Only client computers that try to create new objects are
affected. Accordingly, you can have a disabled application running for an
indefinite period on a client computer or more than one.
Pausing
Application
Pausing to an application and
disabling an application are similar, except pausing is used to disable a
particular running process only, and an application shutdown terminates the
paused status. If you need to pause a process, open the Running Processes folder
and select Pause from the application's context menu and to resume it, choose
Resume.
COM+
Partitioning
Under Windows XP, COM+ 1.5
introduces support for COM+ partitions, including multiple versions of COM+
applications to be installed and configured on the same computer. This
characteristic can save you the cost and time-consuming energy of using numerous
servers to handle several versions of an application. Consequently, on a single
computer each partition has the functionality of a virtual server.
When you install an
application into each partition, you will be generating partition sets which,
map users to the logical servers. Developers can use COM+ to programmatically
generate and configure COM+ partitions. Each generation and configuration task
which a developer should do using the Component Services or Active
Directory Users and Computers administrative tools should also be done by using
COM+ collections, objects, and interfaces or through the Active Directory System
Interface (ADSI).
Application
Partitioning and Aliasing Components
In an enterprise class
environment COM+1.5 provides you and enhanced handling, administrating and
purification of an application using application-partitioning service. Each
application partition service is built from a set of COM+ 1.5 applications.
Partitions support an effective method by offering to every client to use a
group of applications and components that are already exist in client’s
computer. Before the XP
and COM+1.5, a component used to belong only to one COM+ application on a given
computer. The problem with that was, when you needed to install the same
component including the same CLSID in multiple applications you needed multiple
computers. With partitions future you are able to install a component to various
applications by using different partitions. That means, a single computer can
include several partitions. Therefore, every partition can handle its own set of
applications and components.
Again, it was not
possible to apply more than one set of configuration to the same component more
than once before COM+1.5. The new version has futures that allow you to use a
new alias to an existing configured component and therefore you can use a new
CLSID with this alias. As a result you will be able to apply a set of
configuration to your old component like a new component. Aliasing a component
is very important future that XP and Com+1.5 bring us. Therefore, you can design
and develop a piece of your enterprise application and then, if you need you can
also assign various sets of configuration parameters by using aliasing method to
it. Moreover, with this method client can decide which configuration setting and
component or application will be instantiated by generating a part of CLSID.
Once you use alias method to a component the original and the clone are
considered different components by the COM+ services and you can configure them
differently. COM+ services consider the original and the duplicate one as
different components when we use alias method to the component and after all we
can configure them differently. Please note, this is very important: Partitions
are generally configured in active directory therefore, you should assign each
client to partitions in active directory.
Application
Recycling and Programmatic Recycling
Recycling is one of the most
important features in COM+ services for an application. Application recycling
considerably enhances the complete solidity of applications. Memory leaks,
reliance on third-party code, and no scalable resource usage can disintegrate
the implementation of the majority applications over time. To resolve such
problems COM+ application recycling allows the shutting down and restarting of
processes associated with
applications.
You can
configure recycling from the new Pooling & Recycling tab on the
application's properties page. Only a server application can obtain Recycling
services, library applications cannot be configured to use recycling because
they do not own their hosting process.
Application
recycling can compensate for code defects. Memory leakage is one of the most
common of those code defects. Some software may not have sufficient quality
assurance and even released software may have memory leakage problem. Even a
very small memory leak can cause major problems and that may affect the whole
project at the long run.
We can explain
memory leaks with an example from a real life, for instance, if large-scale
software with an "insignificant" memory leak of only 10 bytes per method call,
processes in excess of 25 method calls per second, will leak 25MB of memory in
one day. The process that hosts application will spend this sum of memory and
seriously increase the performance and availability due to program faults that
cannot be predicted beforehand and major memory problems. In previous version,
for this type of problem, developers were only be able to use a technique which
they terminated the hosting process and restarted it manually. Fortunately, XP
brings automatic recycling with COM+ 1.5. When you need to do this just go to
the Pooling & Recycling tab and configure automatic recycling.
You can direct COM+
to shut down your application after a predetermined amount of time by specifying
the Lifetime Limit value to deal with defects in handling other kinds of
resources. For memory, limit default value is zero like lifetime limit, call
limit or activation limit. If you realize that you have made a mistake after you
have done some changes, just click on the restore default button and that will
bring you the default values back. On the application Advanced tab, note that
the lifetime limit semantics are different from the idle time management option.
The Server Process
Shutdown value on the “Advanced” tab specifies the length of idle
time after which the application should be shut down. The lifetime value
indicates the number of minutes before application shutdown, that shows how long
will the process will be alive therefore you can decide the time limit for
keeping the processor
alive.
There are two
more recycling triggers that COM+ provides. Firstly, COM+ can recycle your
application following a given number of method calls into your application when
you indicate such a limit in the Call Limit edit box. The number of calls is
specified as the shared number of calls made on all the objects in the
application. The default value is set to zero. As you recall default, value is
set to zero. Secondly, you may need application recycling after a specific
number of activations. Activations are specified as the sum of objects that COM+
1.5 generated in that application. You identify activation limit in the
Activation Limit edit box please do not forget the default value is set to
zero. Once you triggered
the recycling, COM+ 1.5 directs a new activation request to a new host process,
and waits for accessible client computers to release their references to objects
in the recycled process. In the Expiration Timeout edit box, you can give the
time COM+ 1.5 should wait. Following that expiration timeout, COM+ 1.5 stops the
application. If there are, still client computers holding live references COM
will not care about it. As you will se in box, default expiration timeout is 15
minutes at this point.
Conclusively, you
should keep in mind that for a COM+ application configured as system, service
recycling is not available, and you cannot recycle a paused
application. On the other hand,
you can configure the
recycling parameters programmatically with the COM+ 1.5 Catalog. To configure
memory and time-bound recycling, use the RecycleMemoryLimit and
RecycleLifetimeLimit named properties of the application's Catalog object. If
you want to configure the expiration timeout, you need to use the
RecycleExpirationTimeout named property. Here is an example to programmatically
method.
//usage: "FirstApp" will
be recycled after 250 object
activations //hres =
SetRecycleByActivations("FirstApp",250);
HRESULT
SetRecycleByActivations(LPCSTR lpcszAppName,DWORD
dwActivations) {
//Verify app name is valid
if(_bstr_t(lpcszAppName) ==
_bstr_t(""))
{ return
E_INVALIDARG;
} HRESULT hres =
S_OK; ICOMAdminCatalog2*
pCatalog = NULL; hres =
::CoCreateInstance(CLSID_COMAdminCatalog,
NULL,CLSCTX_SERVER,
IID_ICOMAdminCatalog2,(void**)&pCatalog);
ICatalogObject* pApplication =
NULL; ICatalogCollection*
pApplicationCollection = NULL;
long nCountofApp = 0; int
index = 0;//Index of
Application
//Get the
application collection hres
=
pCatalog->GetCollection(_bstr_t("Applications"),
(IDispatch**)&pApplicationCollection);
pCatalog->Release();
hres =
pApplicationCollection->Populate();
hres =
pApplicationCollection->get_Count(&nCountofApp);
hres =
COMADMIN_E_OBJECT_DOES_NOT_EXIST;
for(index=0; index<nCountofApp;
index++)
{ //Get the current
application hres =
pApplicationCollection->get_Item
(index,(IDispatch**)&pApplication);
_variant_t varName;
pApplication->get_Name(&varName);
_bstr_t bstrName(varName);
if(bstrName ==
_bstr_t(lpcszAppName))
{ long ret =
0; _variant_t
varActivationLimit((long)dwActivations);
hres =
pApplication->put_Value(_bstr_t("RecycleActivationLimit"),
varActivationLimit);
hres =
pApplicationCollection->SaveChanges(&ret);
}
pApplication->Release();
}
pApplicationCollection->Release();
return hres; }
When you need
to configure the call or activation limits programmatically, set the
RecycleCallLimit or RecycleActivationLimit properties. The code provides the
SetRecycleByActivations helper function, which sets a limit of activations for
recycling a specified application.
Application
Pooling
Application pooling is another
important new ‘application lifecycle service’ option, which COM+ 1.5
provides. It is configurable from the new Pooling & Recycling tab on the
application's properties page same as recycling. Pooling services are presented
only for a server application. Library applications do not own their hosting
process therefore; you cannot configure them to use pooling. Library
applications have, in effect, the pooling parameters of whichever server
application happens to load
them. This feature
allocates you to configure the several of replacement processes presented to
host your application's components. With previous version of COM+, all instances
of components from a server application constantly allocate the unchanged
hosting process. Even though this is also the standard COM default, usual COM
local server developers as well had the option of assigning one process for each
object. COM+ 1.5 gives you accurate manipulation powers over the number of
processes are launched by configuring a process pool. The Pool size edit box is
used to configure the pool size in. The default pool size is 1. Just like in
COM+ 1.0, a single process hosts all instances of components from the
application. However, if you set it to a value greater than 1, for each new
instance COM+ 1.5 generates a process until it reaches the pool size. At that,
point COM+ starts multiplexing new instances to the existing processes in a
round-robin fashion. The maximum configurable pool size is 999,999 and this is
sufficient for all functional purposes.
Application pooling
is very helpful as a fault solving technique. If one process has to shut down
because of a fault or exception, the other processes and their clients will not
have a problem. Application pooling also gives you same-computer load balancing.
You do not have to use a separate load balancing service and multiple computers
to allocate different instances to different processes by COM+
1.5.
Configurable
Isolation Levels for Transactions
The new TxIsolationLevel
property or the Component Services administrative tool can be used by COM+
developers to configure an application's isolation level according to need,
helping to increase concurrency, performance, and scalability. This flexibility
allows those with the right amount of expertise to get every ounce of throughput
out of their applications. COM+ 1.0 is very moderate concerning transaction
isolation. It allows only serialized transaction, which is the highest level of
isolation. With serialized transactions, the results obtained from a set of
concurrent transactions are identical to the results obtained by running each
transaction serially. Such a high degree of isolation comes at the expense of
overall system throughput because the resource managers involved have to hold on
to both read and write locks for as long as a transaction is in progress, and
during this time all other transactions are
blocked.
On the other hand, there
are particular issues where you may require dealing system reliability for
decreasing the isolation level as a whole. One of the supplies of an ATM system
(Automatic Teller Machine) is to retrieve the total amount of money in all
customer accounts collective. While it is possible to execute that transaction
with the serialized isolation level, if the bank has hundreds of thousands of
accounts use these ATMs, it may take a few times to complete. The transaction
might timeout and abort because some accounts are being accessed by other
transactions at the same time. However, the quantity of accounts may be an
approval in practice. Overall, when we consider it statistically, if the
transaction is permitted to run at a lower transaction level, it may get the
wrong balance on some accounts, but those incorrect balances would tend to
cancel each other out. The actual resulting error may be acceptable for the
bank's need.
Under
COM+ 1.5 you are able to configure the isolation level for a transactional
component. The Transactions tab has a dropdown listbox with five isolation
levels. The available isolation levels are Any, Read Uncommitted, Read
Committed, Repeatable Read, and Serialized. As you will see in box default,
isolation level is Serialized.
Service
Activation Type
New COM services allow you to
configure a server application to operate as a system service. With this feature
you are able to have your application running immediately after the computer
boots, independent from client activation requests. One more advantage is that a
service application is the only way to have the application operates under the
system identity account. The system account is the very robust account on a
known computer.
You
may see on application Activation tab that it contains the checkbox "Run
application as NT Service”. Once you click on it, you can also configure
the different service parameters by clicking the Setup New Service button,
saving you the difficulty of using the control panel services
applet.
Process
Dumping and Application Dump
Troubleshooting is not an
uncomplicated application in an assembly situation. How do you collect
information on a difficulty without disconcerting the running processes? COM+
now gives a clarification during process dump feature. This characteristic lets
the developer to dump the complete state of a process without terminating it. To
debug and analysis purposes, it is sometimes useful to get a complete memory
dump of an application, especially at the time of a crash. COM+ 1.5 brings a
future that you can configure a dump of a static memory image of the process
hosting your COM+ application. You can use a utility such as WinDbg to view and
analyze this image. All
COM+ 1.5 applications have a new tab on its properties page called Dump. You can
give a location for the image dump and the amount of images to keep there. When
the maximum number of images is reached, a fresh dump image overwrites the
oldest one. The limit number of images you can have COM+ 1.5 keep for you is
200.
There are
several methods to generate a dump file. Categorizing COM+ to dump a memory
image on application fault is the main method. An application's fault in this
context is when an exception is thrown. The second method is to select Dump from
a running application's context menu. Finally, you can also directly ask for a
dump using the DumpProcess method of the ICOMAdminCatalog2 interface, defined
as:
[id(0x1f)] HRESULT
DumpProcess([in] BSTR
bstrApplicationInstanceId,
[in] BSTR bstrDirectoryName,
[in] long lMaximumImages,
[out,retval] BSTR*
pbstrDumpToFile);
COM+
1.5 Catalog root object supports ICOMAdminCatalog2 which derives from the COM+
1.0. After you use the DumpProcess method, you need to give the dump directory
and file name, and you cannot rely on the configured values. Asking for a dump
on a running application is not invasive and the process can keep on running,
and is only inactive temporarily for the period of the dump.
Once COM+ creates a
dumped file, it uses the subsequent naming convention as a file name so that you
can simply connect a dump file with a reported system failure. To stay away from
unnecessary calling DumpProcess, ICOMAdminCatalog2 has an aid technique called
IsProcessDumpSupported that is used to discover whether image dump is
enabled on the computer.
Enhanced
Context Activation Settings
COM+ 1.0 lets you to configure
your component to use JIT activation. In addition, configuring it requires that
the component be activated always in its creator's context by checking the
checkbox "Must be activated in caller's context" on the component properties
page on the Activation tab. This means configuring your component to use
Just-in-Time (JIT) activation needs to have its own context. These two settings
are commonly limited. If you configure a component like that, all activations
will fail. You deal with a similar risk when configuring the component to use
transactions or enforce security access checks for the component—all
require a private context. The COM+ 1.5 Explorer has a solution for this
situation. It includes a redesign of the component Activation tab as well as a
new activation option.
The Activation
Context properties group contains three radio buttons. You can only select one
button at a time. This enforces common exclusion. If you select "Don't force
activation context," you actually choose the regular COM+ context activation
activities. In this method, you can enable JIT activation, transactions, and
security access checks. In fact, as long as transaction support or access
security are enabled, you cannot even select another option, and enabling
security checks sets the selection back to "Don't force activation context" from
any other setting.
New COM services
added a new context activation selection called "Must be activated in the
default context." When you know that clients of the component reside in the
default context, and they are making frequent calls of short duration to your
component, and that your component does not use almost all of COM+ services this
new option can be useful.
A
Short Overview to Web Services in COM+ 1.5
The major change in the .NET
platform is supporting the Web services. They allocate a middle-tier component
in one Web site to call methods on a further middle-tier component at another
Web site, as simply as if the two components were on the same site and computer.
But .NET Web services comes with a cost because companies have to spend time and
money in learning new languages for example C#, and handle with a new
programming model and new class libraries. In most organizations, this is a
nontrivial cost. In COM
components and development expertise to preserve existing investment while
providing a migration path to .NET, COM+ 1.5 can expose any COM+ component as a
Web service as long as the component complies with Web services design
guidelines. The application Activation tab lets you configure SOAP activation
for your application. All you need to do is specify the virtual directory of the
Web service associated with this application, and COM+ provides the necessary
adaptors as a component service. COM+ installs the Web service with IIS, and
generates the proper Web service configuration and information files. You should
note that IIS must be installed on your computer to enable SOAP activation mode
for your application.
Relationship
between COM+ 1.5 and .NET
Developers used several tools
like Microsoft Visual Studio 6.0 to develop COM+ components and establish the
components in COM+ applications to use COM+ services. Today with Microsoft
Visual Studio .NET, managed classes are built and then installed in COM+
applications, in order to get such COM+ services as transactions, object
pooling, and activity semantics. Using Visual Studio .NET and the .NET
Framework gives several rewards more than Visual Studio 6.0 through better
tools, the common language runtime, and a much easier coding syntax. Each
managed class can be hosted in a coexisting COM+ context; thus, managed classes
can take full advantage of all the COM+ services. In the .NET Framework, these
classes are known as serviced components. Any managed class can be modified to
use COM+ services. The Microsoft.ComServices namespace provides various custom
attributes and classes to assist the developer in accessing these services from
managed code.
The
Microsoft .NET Framework now provides equal access to COM+ services in a
consistent and logical manner, and for all languages. Moreover, a number of
innovative parts of the .NET Framework, such as ASP .NET, ADO .NET,
and Messaging, integrate deeply with .NET component services, making use of
services such as transactions and object pooling. This integration provides for
a consistent architecture and programming model. The Microsoft.ComServices
namespace provides various custom attributes and classes that, together with the
ServicedComponent class, provides the programming model to add services to
managed classes.
Using
COM+ Services in .NET
In fact it should be called
“using COM+ technologies under .NET Framework”. COM+ services have
large quantity of enterprise functionality that would be very complicated and
time consuming to duplicate. Even if COM+ services were originally designed for
use with COM+ components, it would be nice if .NET components could also use
them. The problem is that compiled .NET components (assemblies) and compiled COM
components stay on different structural standards; COM components conforms to
COM’s binary model and .NET components conforms to the structures outlined
in the CLS (Common Language Specification). In order to make .NET components
make use of services originally designed for components that fit a different
model there are two basic challenges that need to be met. .NET components need
to be able to access the objects in the COM+ services object model so that they
can refer to them in
code.
Developers can
develop specific components that manipulate COM+ services exclusively in managed
code or in any combination of managed and unmanaged code. The services will
spring between the components because the context of each component is hosted in
COM+ where the context flows appropriately from one component to another. The
common language runtime and COM+ services are working together to automatically
generate type library information and perform registration so that the managed
class appears in the COM+ catalog. However, only COM+ services the context
information, while the actual implementation and execution is performed within
the runtime. In the following code, the class Account derives from the
class System.ServicedComponent. Deriving from ServicedComponent
ensures that the contexts of Account objects are hosted in COM+.
Further modifications that are required for this class are highlighted in the
code.
The
Transaction attribute marks the class as requiring a transaction, which
is equivalent to using the COM+ Explorer to set the transaction support on a
COM+ component. The AutoComplete attribute is used to specify that the
runtime must automatically call the SetAbort function for the transaction
if an exception is thrown during the execution of the method; otherwise, a
SetComplete function is called. Various assembly level attributes are
also used to capture COM+ application level registration details.
#using
<mscorlib.dll>
using
System; using
Microsoft::ComServices; using
System::Runtime::CompilerServices;
namespace
ATMComponent { [Transaction(TransactionOption.Required)] public
class ATMAccount :
ServicedComponent {
[AutoComplete]
bool SendIt(int
accountNum, double
amountOfAcc)
{ // do
something }
}
// - Registrations Part -
// COM+
Application Name to add the
Component
[assembly:
ApplicationName("ATMComponent")]
// You need to add a Strong Name for
Assembly
[assembly:
AssemblyKeyFileAttribute("ATMComponent.snk")] }
Focusing
on the new System.EnterpriseServices namespace
Focusing on the new
System.EnterpriseServices namespace, we will go through COM+ services accessible
to .NET. In addition, we will focus on how attributes engage in recreation an
important role. After that, we will generate a minimal serviced component. Than
we will considerate the registering our simple with
COM+.
The reason of
the components and interfaces enclosed in System.EnterpriseServices is to
provide access to COM+1.5 services from the .NET platform. This edition of the
design is targeted for beta 2 of .NET on XP. The objective of
System.EnterpriseServices for .NET beta 2 is to enable objects in .NET to make
use of COM+ services and to participate in services with both managed and
unmanaged objects. The first scenario is for two managed objects to participate
in a transaction initiated from a managed client. In this case, both managed
classes must be implemented as COM components. Further transactional attributes
are added to the classes. Then the classes are registered in the COM+ catalog
using the tool described in this document. A further scenario is using one
managed object and one COM+ object within one transaction. This can be achieved
in a similar way by implementing the managed object as a component and
registering the managed component. Sample code for the first scenario is shown
below and the process required deploying and running the
components.
//
----------------------------------------------------------------- //
ServicesApp.cpp //
-----------------------------------------------------------------
#using
<mscorlib.dll>
using
System; using
System::Runtime::InteropServices; using
System::EnterpriseServices;
//COM+
application name while it appears in the COM+
catalog [assembly:
ApplicationName(“TestServicesApp”)] //Strong
name used for
assembly [assembly:
AssemblyKeyFileAttribute(“TestServicesApp.snk”)]
[Transaction] public
class Account :
ServicedComponent {
[AutoComplete] void
ATMDebit(int amount)
{ // Do a few more work,
throw exception to terminate transaction
// or else transaction
commits
} }
class
client {
static int main()
{ Account daccount = new
Account();
daccount.ATMDebit(100);
return 0;
} }
What
is New in System.EnterpriseServices?
Latest advance in .NET is the
System.EnterpriseServices namespace. There we will come across the
ServicedComponent class and the entire required attribute classes needed
to create COM+ components. From creation to use there are four fundamental
steps to COM+ component development. First, you need to inherit your class from
ServicedComponent. Second, you have to apply attributes to your assembly,
classes, and methods. Than third, you will strong name the assembly. Finally,
you will register the component with COM+. Through .NET, you still have access
to all the COM+ services available from COM+ 1.5. These COM+ services
contain queued components, just in time activation, object construction, object
pooling, automatic transaction processing, and some more.
System.EnterpriseServices
Futures and Deployment
Additional to its enhanced and
modern design, .NET is actually a fundamental component technology. Like
COM, .NET supports with the means to fast and professionally build binary
components, and Microsoft spends effort for .NET to create ultimately succeed
COM. Unlike COM+, .NET does not provide its own component services. Instead,
.NET relies on COM+ to make it available with instance management, transactions,
activity-based synchronization, rough role-based security, disconnected
asynchronous queued components, and loosely coupled events. The .NET namespace
that contains the types necessary to use COM+ services was named
System.EnterpriseServices to reflect the pivotal role it plays in
building .NET enterprise applications.
While designing and
developing a COM+ component, consider how you would adjust components in the
Component Services snap. You will need to decide COM+ application
name. You have to choose application activation type, server, or
library. Will you use objects pooled or not? Do you use a
construction string? Component configuration can (and sometimes must be)
applied at design time, through attributes. These attributes are later
read from the assembly’s metadata as the component is being
registered. We will get to registration later. Important note is all
attributes are optional, and if attributes are not applied defaults will be used
for the registration process. The metadata level they pertain to, and the
default value assigned to the COM+ catalog if the attribute is not
applied. In some cases, attributes must work hand in hand with code
implementation. This is still handy with .NET because a serviced
component’s class constructor cannot accept
arguments.
With
Visual Studio.NET Beta2, assigning a strong name is easy. Go to the
project explorer, right click the project name, and select
Properties. Under the Common Properties folder, on the left,
select Strong Name. Check the Generate strong name using:
check box and then the Key file: option. Click the Generate
Key button and you are all done. Now, we are ready to compile. After
compile, we need register the component using
COM+.
A simple .NET
serviced component
namespace
SimpleNamespace {
using System;
using
System::EnterpriseServices;
using System::Windows::Forms; //for the MessageBox class
public interface IMessage {
void ShowMessage( );
} ///
<summary> /// .NET
serviced component ///
</summary> public
class
SimpleComponent:ServicedComponent,IMessage
{ SimpleComponent( )
{}//constructor void
ShowMessage( )
{
MessageBox.Show("Hello!","SimpleComponent");
}
} }
Apply
Attributes
Practically all technology
uses the term "attributes," that confuses programmers and users. Certainly, an
attribute is a property of an item that gives information about the item, its
performance, or its requirements. C++ attributes in Visual Studio .NET are used
to write four kinds of code: OLE DB consumer code, performance counter code, Web
Services and ATL Server code, and COM objects. In this article, I will restrict
myself to the Visual C++ COM attributes that are used to define the behavior of
COM components. The concept of C++ attributes is quite simple.
An attribute is
applied to a class or function by declaring it before the code, using square
brackets in the same style as IDL. I have deliberately chosen this attribute as
an example because it has the same name as the IDL statement that it replaces.
This declaration is in a header or CPP file, and the idea is that the code which
specifies that the server DLL has an implementation of a coclass called CManager
has been moved out of the IDL file and put in the implementation files. This
makes perfect sense because the coclass statement in a type library is about
implementation; it describes a component that implements one or more
interfaces.
Components
using COM+ services are suggested to specify an assembly header with attributes.
Either an assembly name is obtained from the metadata, from the assembly's
FullName, or the value obtained from an ApplicationName attribute. If the
assembly is tagged with an ApplicationID or Guid attribute, all searches for the
application are based on that guid, not on the application name. Additional,
component configuration can applied at design time, through
attributes
If a class
in .NET works with COM+ services then it is need to be registered in a COM+
application in the COM+ catalog as a usual COM+ component. When an instance of
the class is created within .NET, this registration is done automatically based
on the attributes in the assembly.
However, if a new
instance of the class is required from an unmanaged environment, then the
assembly must be registered manually. This can be achieved using the tool,
regsvcs. When writing COM+ components, think how you would adjust components in
the Component Services. What is the COM+ application name? Is the
application activation type, server, or library? Are my objects
pooled? Do I use a construction string?
What
is a .NET Component?
Components are defined in
various ways. However, some general observations may be made. Components are
interchangeable software parts that are both an artifact of
"industrialized" systems and the impetus for their success. In the Component
layer of the .NET Platform, components are created as Assemblies for interoping
by means of Metadata "Blueprints" as applications and with .NET basic system
layers.
Basically
the .NET Platform creates and works with components as its fundamental building
block. A .NET Platform component is basically an interchangeable software part,
built in any .NET language with metadata "blueprints" for assembly,
independently deployable in a plug-in fashion and ready to interop with other
programs. A .NET component that uses COM+ services is called a serviced
component to distinguish it from the standard managed components in
.NET.
Strongly
Named .NET Components
Now, we will learn what the
strong name assembly (.NET Components) is.
When a configured class is developed, it
must be compiled. After compiling the code, there are two things to consider.
Primarily, the COM+ integration needs that the compiled assembly be strongly
named. You must generate a key by running the Strong Name Utility named sn.exe
to create a strongly named assembly. Once you compile your strong named assembly
you must reference the key, which is stored in a file, from within your
component's code using an assembly-level attribute called
AssemblyKeyFileAttribute from the System.Reflection
namespace.
#using
<mscorlib.dll> using
System; using
System::EnterpriseServices; using
System::Reflection;
[assembly:
ApplicationName("FirstApp")] [assembly:
ApplicationActivation(ActivationOption.Library)]
//
AssemblyKeyFile attribute references keyfile
generated // by sn.exe -
assembly will have strong
name [assembly:
AssemblyKeyFile("thiskeyfile")]
namespace
ESExample { ••• }
Second,
when you compile your strongly named assembly, you must reference the assembly
that exports the types in the System.EnterpriseServices namespace,
System.EnterpriseServices.dll. Here are the commands for generating a key and
compiling a configured class:
sn
-k thiskeyfile Cl
/out:ThisExample.dll
/t:library
/r:System.EnterpriseServices.dll FirstCfgClass.cpp
Register
.NET Components with COM+
COM+ has two forms of
registration, dynamic and manual. Both are practically effortless,
although for the purposes of this sample, dynamic is satisfactory. Dynamic
registration has a few
requirements.
1.
Assembly must have strong
name. 2. Assembly
may not be in the global assembly
cache. 3. Assembly
must be used by managed (.NET)
clients. 4.
Assembly activation type must be
Library. This may
appear restrictive, but it actually includes many cases. I believe you are
thinking, activation type must be Library. I do not create any
Library COM+ components! Well, either with .NET, you will have the
serviced component’s client on the same computer, or the client will be
remoting to a surrogate application to access the COM+ components.
Because of this, a pure .NET solution will be able to use dynamic registration
most of the time.
Dynamic registration
actually occurs the first time the client instantiates the serviced component,
and only happens once for that version of the assembly. You will notice a
lag the first time the component is accessed while the COM+ catalog is
updated. The code is meant to track the number of objects that exist in
memory and how many of those objects are active during or after a certain
activity.
Notice
there is indeed a pool of five objects and the just in time activation works
after the initial call is made to the object. It seems that once the
object is instantiated, it’s activated until a method is called.
Once a method is called, the object is only activated during calls. This
means you should hold off object instantiation until you are about to use
object.
Migration
Strategy
After you have decided to
migrate part or all of an existing application to .NET, you will need to make a
decision how finest to method the migration. This article introduces the
horizontal and vertical methods to application migration. The issues you need to
care about in forming a migration strategy are discussed simultaneously with
some common migration scenarios.
Vertical
and Horizontal Migration
Horizontal migration involves
replacing a whole tier of your application. For example, you may choose to
initially replace the ASP code within your Web-based presentation tier, or you
may replace the COM code within your middle tier as the initial migration step.
Vertical migration involves isolating and replacing a part of your application
from side to side all n tiers.
Component
Design
This article also presents
guidelines relating to .NET/COM migration and interoperability to component
design issues. When calling between .NET and COM environments through the
interoperability layer, the CCW or the RCW (depending on the direction of the
call) must translate the data on the call stack between the two environments.
Certain data types (referred to as blittable types) do not require translation.
Examples of blittable types include integers, longs, and floats (Singles and
Doubles). Nonblittable types require translation by the wrappers.
A Visual Basic BSTR
is an example of a nonblittable type. As you migrate your application to .NET,
you should minimize the use of nonblittable types between managed and unmanaged
code because the associated conversion overhead affects
performance.
blittable
data types
Most data types have a common
representation in both managed and unmanaged memory and do not require special
handling by the interop marshaler. These types are called blittable types
because they do not require conversion when passed between managed and unmanaged
code. Blittable types have a common representation across the interop boundary.
Integer and floating-point types are blittable. Arrays and structures of
blittable types are also blittable.
non
blittable data types
Non-blittable types have
different or ambiguous representations in managed and unmanaged languages. These
types are called non-blittable types because they can require conversion when
they are marshaled between managed and unmanaged code. For example, managed
strings are non-blittable types because they can have several different
unmanaged representations, some of which might require conversion. Strings,
dates, and objects are examples on non-blittable types that are converted during
the marshaling process.
Existing
COM Components and Managed Clients
While you move your clients to
.NET, take into account the interfaces exposed by your existing COM components.
Typically, you will want to expose your existing COM components to your new .NET
clients while leaving existing COM clients in place. Imagine, how you want to
cover your existing components for both environments and care about future
managed clients while you design your
interfaces.
When
migrate your components to .NET is the tlbimp utility to generate an
automatic RCW for your application. This RCW, by default, exposes the same
interfaces (and by definition the same properties and methods) as your existing
component. In many cases, conventional COM-style interfaces exposed by the RCW
will not be natural to use from managed code. Managed code developers will
expect to be able to take advantage of such features as,
- Parameterized constructors
- Inheritance
- Static methods
You
should consider writing a custom wrapper class for your COM object to submit
your managed clients these abilities and to create interfaces more suited to the
managed code environment,. This wrapper class consumes the RCW for your COM
components internally and delegates most calls to your existing COM components.
Some calls may perform more complex data-type conversions such as mapping
between ADO .NET datasets and ADO recordsets. Over time, you can move more and
more of the functionality from the COM component to the wrapper without
affecting your managed
clients. There are a
number of factors to consider when deciding whether to use an RCW or a
custom-managed wrapper class. Note the TlbImp utility, which is included
in the SDK, can convert COM type libraries to .NET Framework metadata. Once the
type library is converted to metadata, managed clients can call the COM type
seamlessly. For ease of use, always provide type information in a type
library.
Creating an
RCW and exposing the existing interfaces may be an appropriate strategy if your
components have a large numbers of clients who are accustomed to your existing
object model,. For example, the object model in Microsoft Excel is widely used
by Excel developers using Microsoft Visual Basic for Applications. The object
model is highly structured and maps well to the features and user interface
presented by Excel. Customers are very familiar with the existing object model
and would require significant retraining if the object model were changed
substantially. In this instance, using the standard RCW might be
appropriate.
When
writing custom-managed wrappers for COM interfaces that make heavy use of get
and set properties remember that these interfaces—previously described as
chatty interfaces—are used from managed code through an RCW, each property
call crosses the interoperability boundary and incurs overhead. For a simple
interface with minimal marshaling work, the interoperability overhead will be
roughly 30 to 50 assembly instructions. This overhead is minimal for a method
that performs a significant amount of work internally, but it would represent a
large percentage overhead for a simple property
access.
Consider
writing a custom-managed wrapper and move the functionality represented by the
chatty interface from the COM component to the wrapper if you expect the clients
of your COM components to move to .NET soon, other, less chatty interfaces could
be left implemented in the COM object and could be delegated to by the managed
wrapper.
You will be
able to minimize the interop call overhead and have a more natural interface to
your object from managed code by repartitioning of code enables. An additional
benefit of writing a custom-managed wrapper is that it allows you to move the
remoting boundary as illustrated in Figure 8. This figure illustrates both a
standard RCW and a custom-managed wrapper for a COM component. It shows how you
can provide an interface more suited to managed clients, as well as how you can
move the remoting boundary so that you can make .NET remoting calls.
Implement the class
interface The class
interface, is not explicitly defined in managed code. It is an interface that
exposes all public methods, properties, fields, and events that are explicitly
exposed on the .NET object. This interface can be a dual or dispatch-only
interface. The class interface receives the name of the .NET class itself,
preceded by an underscore. For example, for class Mammals, the class interface
is _Mammals. For derived classes, the class interface also renders all public
methods, properties, and fields of the base class. The derived class also
renders a class interface for each base class. For example, if class Mammals
extends class MammalMainclass that itself extends System.Object, the .NET object
exposes to COM clients three class interfaces named _Mammals, _MammalMainclass,
and _Object.
The COM
client can obtain a pointer to a class interface named Mammals, which is
described in the type library that the Type Library Exporter (Tlbexp.exe) tool
generates. If the Mammals class implemented one or more interfaces, the
interfaces would appear under the
coclass.
[odl,
uuid(0000...0000), hidden, dual, nonextensible,
oleautomation] interface
_Mammals : IDispatch
{ [id(0x00000000),
propget] HRESULT ToString([out, retval]
BSTR*
pRetVal);
[id(0x60020001)] HRESULT Equals([in] VARIANT obj, [out,
retval] VARIANT_BOOL*
pRetVal);
[id(0x60020002)] HRESULT GetHashCodes([out, retval] short*
pRetVal); [id(0x60020003)]
HRESULT GetType([out, retval] _Type**
pRetVal); [id(0x6002000d)]
HRESULT EatIt();
[id(0x6002000e)] HRESULT
GetBreathe();
[id(0x6002000f)] HRESULT
GoSleep();
}
[uuid(0000...0000)] coclass
Mammals
{ [default] interface
_Mammals;
}
Class
interface generating is optional. If you do not select any other option COM
interop generates a dispatch-only interface for each class you export to a type
library as a default. You can prevent or modify the automatic creation of this
interface by applying the ClassInterfaceAttribute to your class. Although the
class interface can ease the task of exposing managed classes to COM, its uses
are limited.
Use primary interop
assemblies Unlike
other .NET assemblies, an interop assembly, contains no implementation code.
Interop assemblies contain only the type definitions of types that are already
implemented in COM components. It is from these type definitions that the CLR
generates the RCW to allow managed code to bind to the types at compile time and
provides information to the CLR about how the types should be marshaled at run
time. Any number of assemblies can be generated for a COM type (using
tlbimp is one method for generating an interop assembly). However, only
one assembly is known as the Primary Interop Assembly (PIA). The PIA contains
the software publisher's description of the types and is signed and authorized
for use by that publisher. Because the PIA is signed by the software publisher
and contains the PrimaryInteropAssembly attribute, it can easily be
distinguished from other interop assemblies that define the same COM types.
Please note that, the project system checks if a primary interop assembly for
the specified type library exists. If it can found, then that assembly is used
as the wrapper for the COM object's methods and properties. If not found, the
behavior is the same as if "tlbimp" were
specified.
Primary
Interop Assemblies are important because they uniquely identify a type. Types
defined within an interop assembly that was not provided by the component
publisher are not compatible with types defined in the primary interop
assemblies. For example, consider two developers in the same company who are
writing managed code that will interoperate with an existing third-party
supplied COM component. One developer acquires the PIA from the component
publisher. The other developer generates his own interop assembly by running
tlbimp on against the COM object's type library. Each developer's code
works properly until one of the developers (or worse yet, a third developer or
customer) tries to pass the object to the other developer's code. This results
in a type mismatch exception; although they both represent the same COM object,
the type checking functionality of the CLR recognizes the two assemblies as
containing different
types.
You should
obtain the PIA for any COM components you use in your applications. Doing so
helps to prevent type incompatibilities in code written by developers using the
same COM object. You should also provide PIAs for any components you develop
that might be used by others, especially if third party developers or customers
will use these components in their applications.
Future
Changes to Visual C++.NET and COM+ Services
That wraps up our coverage of
some of the new COM+ features. Next, we’re going to take a quick look at
what changes are being added to Visual C++.NET to make developing COM+
applications easier. However, instead of implementing these features in the COM+
runtime and exposing them to tools such as Visual C++, a shorter-term solution
was used, which is described below.
The COM+ features
we’ve been discussing are great, but as C++ developers we still need some
way to harness all these features. Writing COM services in C++ is still a bit
tedious, although ATL has made it much easier. Developing COM+ services with C++
is difficult because the COM and C++ programming models don’t exactly
“mesh.” Frameworks like ATL make development easier, but they still
require some knowledge of low-level COM. The Visual C++ and ATL teams have
joined together to make COM development easier through something called
attribute-based programming.
|