New Interfaces
In addition to simply redesigning the architecture of MTS, COM+ also adds significant functionality for developers in the form of new interfaces in the COM+ Service Type Library.
One of the new interfaces VB developers can use is IContextState. You can get a reference to it through the IObjectContext interface because it is exposed as a property of the ObjectContext object.
Dim objcx as ObjectContext Dim objcs As IContextState Set objcx = GetObjectContext Set objcs = objcx
This interface contains four methods that get and set the two values that COM+ uses to determine the outcome of the current transaction, and whether to deactivate components when a method call returns. The values are often called the Happy and Done flags, respectively.
Method |
Description |
GetMyTransactionVote(ptxVote as tagTransactionVote) |
Passed in a variable by reference and populates it with 0=TxCommit or 1=TxAbort (the Happy flag). |
GetDeactivateOnReturn(pbDeactivate as Boolean) |
Passed in a Boolean variable by reference and populates it with the Done flag. |
SetDeactivateOnReturn(bDeactivate as Boolean) |
Passed in a Boolean to set the Done flag. |
SetMyTransactionVote(txVote As tagTransactionVote) |
Passed in a constant (0=TxCommit, 1=TxAbort) that sets the Happy flag. |
You can use these methods to apply finer-grained control over both values, now setting and reading them individually rather than by calling SetComplete and SetAbort, which set them both. More importantly, these methods raise errors when the component is not running in a transaction or is not configured for JIT, a characteristic you can use to programmatically enforce how the component should be used.
A second new interface—and one that is a welcome addition—is IObjectConstruct. This interface solves the common problem of how to pass simple information into a component upon activation, of which a database connection string is a primary example being. In the MTS implementation, developers chose between passing an ADO connection string from the client application to each method of the component, hard coding the string within the components, using a DSN, or reading it from the system Registry with each method call. Each of these options has a downside that involves tradeoffs between maintainability and performance. COM+ solves this problem with IObjectConstruct by allowing you to implement this interface within your component. Doing so enables COM+ to call the implementation of the Construct method of IObjectConstruct each time an instance of the component is created. This is analogous to the Initialize event of a VB class module, or the command line parameters that are available to executable files. However, COM+ will call the interface only if object construction is enabled on the Activation tab of the component’s property sheet (see Figure 4).
Figure 4: The component properties dialog of the Component Services snap-in allows for the calling of the IobjectConstruct interface.
The Construct method passes in an object of type IObjectConstructString that exposes a single property called ConstructString, which contains the string that is stored in the Activation tab.
Implements IObjectConstruct Private Sub IObjectConstruct_Construct(ByVal _ pCtorObj As Object) ' Get the connect string from the constructor mstrConnectString = pCtorObj.ConstructString End Sub
After you read the value of ConstructString, you can store its contents in a private variable for use in your methods. The end result is that components require fewer methods and can be administratively configured to communicate with different servers and databases through the Component Services snap-in.