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 Page
As 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?
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.
- Assembly must have strong name.
- Assembly may not be in the global assembly cache.
- Assembly must be used by managed (.NET) clients.
- 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.