Using the Upgrade Wizard to upgrade Visual Basic 6.0 MTS and COM+ applications to.NET is mostly a straightforward process; however, there are a few issues to bear in mind. Chapter 15 addresses those issues for different VB6 components -com+ object pooling, com+ application security, com+ object constructor strings, com+ transactions- indicating not only the output of the upgrade wizard after it is applied to the component, but also the manual changes that you must make to complete the upgrade to Visual Basic .NET.
Microsoft Transaction Server (MTS) is a technology primarily intended for multiuser server applications. In addition to supporting distributed transactions, MTS extends COM’s security model and provides scalability services, connection management, thread pooling, and an administration structure. This environment provides an easy way to build and deploy scalable server applications, making available a suitable distributed-enabled atmosphere for COM objects running in the middle tier. When Microsoft Transaction Server is installed, middle-tier components and objects should be run inside the MTS environment whether or not they are involved in transactions.
COM+ is an extension to the Component Object Model (COM) and the MTS infrastructure. The consolidation of these two programming models makes it easier to develop distributed applications by unifying the development, deployment, debugging, and maintenance of an application that would formerly have relied on COM for certain services and MTS for others.
MTS can be used to build n-tier applications. Using VB 6.0, you develop COM DLL components that run on middle-tiered servers under the control of MTS. When clients call these COM DLLs, the Windows operating system routes the requests to MTS automatically. Other services provided by MTS that are relevant to upgrade efforts include component transactions, object brokering, resource pooling, just-in-time activation and administration.
A possible upgrade strategy is to use proxy COM classes that are accessed through interoperability. While this strategy is adequate in some scenarios, using proxy classes is not always possible or appropriate. In some cases you need to re-implement the MTS and COM+ services using the .NET Framework instead.
The System.EnterpriseServices namespace in the .NET Framework contains classes that offer similar functionality and provide an interface to mechanisms used by COM+. This makes it possible to build enterprise applications using .NET objects while retaining access to COM+ services.
The .NET Framework relies on COM+ to provide it with distributed transactions, component instance management, role-based security, queued components and events. The System.EnterpriseServices namespace makes COM+ part of the .NET Framework, in essence, by supplying all the types, classes, and objects necessary to use COM+ services.
A .NET component that uses COM+ services is referred to as a serviced component. When you create serviced components you should consider the following:
The ServiceComponent class, in the System.EnterpriseServices namespace, is the base object of all classes using COM+ services. To deploy and use a ServicedComponent object it is necessary to sign the corresponding component with a strong name, consisting of the assembly’s identity (its simple text name and version number, which are required, and the culture information if it is provided) plus a public key and a digital signature. This task can be accomplished by using the Strong Name tool (Sn.exe), a command-line tool distributed with the .NET Framework to create a key pair file with the file name extension .snk. The generated file must be copied to the component’s source code folder.
XML Web services are published on Web servers, such as IIS, and accessed using HTTP. These HTTP packets contain the input and output parameters of calls to a method that is implemented on the server and are encoded in SOAP. To use an XML Web service, you need to know the URL where the service is exposed and the name of the method you want to call, and you must provide the input parameters to the method.
While it is helpful to have some understanding of the infrastructure that underlies
XML Web services, COM+ makes it easy to create and use them.
Any COM+ application can be exposed as an XML Web service. Clients can then make remote calls to the methods in the default interfaces of the application’s configured components. You can use the Component Services administrative tool to create an IIS virtual root directory that calls the component methods by using SOAP.
You do not need to do any special programming when writing the components, except that the methods that you want to expose must be in the default interface and the component must be configured in the server’s COM+ catalog. You do not need to write code to communicate through a network interface or to parse SOAP.
When you expose a COM+ application as an XML Web service, detailed information about the syntax of all the methods that are available from an XML Web service is published automatically, using the Web Services Description Language (WSDL). Clients use this information to communicate with the XML Web service.
COM+ provides two ways to do this:
services created by exposing COM+ applications. CAO mode increases performance by using persistent connections, which is a feature that is not supported by the current SOAP standard.
Both methods allow client applications to call the methods of XML Web services without having to write code to communicate through a network interface or to parse SOAP.
First, the upgrade wizard is used to upgrade the server component, and then the necessary manual changes to create an equivalent component in Visual Basic .NET are made. The scenario is completed by upgrading the client component.
The upgrade wizard converts most of the module’s functionality correctly, but there are several minor changes that you must make before you have a fully functional and accurate server component.
The COM+ Compensating Resource Manager (CRM) Services can be used to integrate application resources with Microsoft Distributed Transaction Coordinator (DTC) transactions.
There are some classes and interfaces provided by the COM+ Services Library that allow developers to take advantage of CRM Services, such as CRMClerk, CRMRecoveryClerk, ICrmFormatLogRecords, ICrmMonitorLogRecords and tagCrmLogRecordRead. These services are also provided in the .NET Framework in the System.EnterpriseServices.CompensatingResourceManager namespace.
Developers can use the CRMClerk class to handle log-related operations. The equivalent of this class in the .NET Framework is System.EnterpriseServices.CompensatingResourceManager.Clerk.
Visual Basic 6.0 developers can implement ICrmCompensatorVariants interface to handle log-related issues. To get similar functionality in Visual Basic .NET, the class supporting ICrmCompensatorVariants must inherit from System.EnterpriseServices.CompensatingResourceManager.Compensator.
A CRM consists of two separate COM co-classes, Worker and Compensator, which must be implemented. The Worker class initiates changes, and the Compensator class either commits the changes or rolls them back.
Components that are developed using Visual Basic 6.0 cannot be pooled because COM+ object pooling requires multi-threaded apartment (MTA) components, and Visual Basic 6.0 components use the single-threaded apartment model. However, a Visual Basic 6.0 application can detect whether an object can be pooled or not, using the IObjectControl interface.
In Visual Basic 6.0, the ObjectControl class provides the same functionality as IObjectControl. In Visual Basic .NET, the ServicedComponent class in the System.EnterpriseServices namespace provides similar functionality. Therefore, a Visual Basic .NET class that inherits from ServicesComponent is capable of pooling.
To make an object poolable, decorate the class with the ObjectPooling attribute and add a reference to the System.EnterpriseServices namespace. Also, pooled objects may only run in server applications — they may not be configured to run as a library.
COM+ applications can provide controlled access to resources. Using roles, developers can administratively construct an authorization policy for an application, choosing which users can access which resources, even down to the method level, if necessary. Additionally, roles provide a framework for enforcing security-checking within code if an application requires finer-grained access control.
Role-based security is built on a general mechanism that enables developers to retrieve security information that is related to all upstream callers in the chain of calls to one particular component.
Visual Basic 6.0 developers can handle user-role information using the SecurityCallContext class. In Visual Basic 6.0, developers can access the members of SecurityCallContext without declaring a specific instance of this type, by using the GetSecurityCallContext global function provided by the IGetSecurityCallContext interface and accessing the object returned.
Visual Basic .NET developers can get similar functionality from GetSecurityCallContext through the CurrentCall property of a static instance of System.EnterpriseServices.SecurityCallContext.
Visual Basic 6.0 developers can use SecurityCallers and SecurityIdentity to manipulate information about a caller in a secured application. In Visual Basic .NET, the SecurityCallers and SecurityIdentity classes are included in the System.EnterpriseServices namespace and provide similar functionality.
COM+ object constructor strings are initialization strings that are administratively specified for a component. These object constructor strings can be used to write a single component with a degree of generality that allows it to be later customized for a particular task; in other words, it allows you to create parameterized object constructors.
Visual Basic 6.0 developers can use this COM+ feature by implementing the IObjectConstruct and IObjectConstructString interfaces. In Visual Basic .NET, the ServicedComponent class in the System.EnterpriseServices namespace provides the Construct method, which provides a similar functionality. A Visual Basic .NET class that supports construction strings must inherit from System.EnterpriseServices.ServicedComponent. You can emulate the Construct method from IObjectConstruct by overriding the Construct method from the ServicedComponent class.
In Visual Basic 6.0, you can use the MTSTransactionMode property to set the transactional behavior of a user class. This property is only used by components that are running in the Microsoft Transaction Server, and has no effect if the component is run outside of the MTS.
In Visual Basic .NET, developers can use System.EnterpriseServices namespace to get transactional functionality for their .NET classes. To be treated as a transactional class, a Visual Basic .NET class should inherit from ServicedComponent and include the proper transaction attribute. Transactional Visual Basic 6.0 classes should be upgraded to serviced components.
The MTSTransactionMode values correspond to the System.EnterpriseServices.TransactionOption .NET Framework enumeration that contains the automatic transaction type requested by a COM+ component.
To create a Visual Basic .NET project that references transactional classes, the latter should inherit from ServicedComponent and contain transactional attributes, and you should eliminate calls to GetObjectContext, using instead the ContextUtil class.
The Visual Basic 6.0 MTSTransactionMode attribute controls whether transactions are required for a class. This attribute should be mapped to the corresponding value from System.EnterpriseServices.TransactionOption.
All COM+ transaction related classes are supported by Visual Basic 6.0, and almost every class has an equivalent class in the .NET Framework. The only exception is the ITransaction interface, which does not have a semantic equivalent in Visual Basic .NET.
The COM+ event system introduces Visual Basic programmers to the concept of a loosely coupled event (LCE) system in which event consumers (called subscribers) do not have to declare a variable against the event provider (called a publisher). Instead, the subscriber and publisher both rely on an interface definition in the form of a COM+ event class.
As event classes define the interface that the publisher calls and the subscriber implements they form the primary mechanism for decoupling the event. You must install the event component inside the Component Services dialog box by selecting the Install new event class(es) option.
After you install the event class, you must create a subscriber to receive the new event and implement the interface defined by the event class.
The publisher can be a standard module, dynamic link library, or a regular COM+ application, which is a COM+ application that you create by selecting the Install new class(es) option inside the Component Service dialog box. The user application in the client tier is the subscriber that will capture the event later.
Message Queuing (also known as MSMQ) constitutes a platform that supports flexible and reliable communication between applications. Different applications can be integrated by implementing a communication environment where messages can be sent between applications in networks with varying degrees of reliability. Message Queuing enables applications that are running at different times to communicate across heterogeneous networks in a reliable manner, in spite of any unreliable components in the system.
A task is invoked asynchronously when it is called without waiting for it to terminate and produce a result. Using this type of execution allows applications to have better responsiveness and improved usage of the available resources. This mode of processing can be achieved using COM+ Queued Components or Message Queuing.
Using Message Queuing, an application can place data into a queue, which is a message store that allows applications to communicate indirectly. Queues will preserve messages until they are not needed anymore. While the data is in the queue it can be retrieved by the same application that generated it or by other applications. Message Queuing queues can receive messages that represent a task to be executed asynchronously by a server process that retrieved the message.
In an unreliable distributed computing environment, it is quite possible that not all of the servers involved in a transaction are available at a given time. For example, a customer purchase order may need to be temporarily saved in a message store while the necessary remote SQL server becomes available. Message Queuing was designed and developed with this kind of situation in mind.
Until recently, the primary ways to access the services provided by Message Queuing were through the MSMQ COM API and C API. The COM API is available to COM clients such as Visual Basic 6.0, but it can also be accessed in Visual Basic .NET using COM interoperability. However, with the introduction of the .NET Framework, the System.Messaging namespace provides a new and convenient way (a group of classes) to access MSMQ in a managed environment.
The recommended solution when it is necessary to communicate between applications written in VB 6.0 and Visual Basic .NET is to keep the entire MSMQ communication layer consistent. For example, all of the application’s communication layer should be written in Visual Basic 6.0 or Visual Basic .NET. In such cases, it may be necessary to create new communication classes that will interact locally with components written in other languages.
The COM+ Queued Components service provides an efficient way to invoke and execute components asynchronously using Message Queuing. Setting up this kind of processing can be done relatively easily by deriving the asynchronous class from System.EnterpriseServices.ServicedComponent.