Creating and Managing Microsoft Windows–Serviced Components CERTIFICATION OBJECTIVES 3.01 Creating and consuming a Serviced Component 3.02 Implementing a Serviced Component 3.03 Creating
Trang 1Creating and Managing Microsoft Windows–Serviced Components
CERTIFICATION OBJECTIVES
3.01 Creating and consuming a Serviced
Component 3.02 Implementing a Serviced Component 3.03 Creating Interfaces That Are Visible
to COM 3.04 Creating a strongly Named Assembly 3.05 Registering the Component in the
Global Assembly Cache 3.06 Managing the Component by Using
the Component Services Tool
✓ Two-Minute Drill
Q&A Self Test
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
Chapter 3
Composite Default screen
Trang 2CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
You may suppose that now that you have the NET Framework and assemblies that
don’t need to be registered in the Registry, you have finally moved beyond the COMcomponents Nothing can be further from the truth; there are millions of COMcomponents in production, and a large number of applications use MTS and Component Services
So, what are you to do? Throw away all the COM components and rewrite them in Visual
Basic NET? I don’t think so! You need to find a way that will allow the two environments to
coexist, and that is where serviced components come in.
A serviced component is a NET component that has been configured to work
in the Component Services environments of Windows 2000 and later This chapterwill explore the world of Component Services, which includes COM and servicedcomponents
CERTIFICATION OBJECTIVE 3.01
Component Services
The Component Services environment of Windows 2000 or later provides the
services of an object resource broker (ORB) The ORB allows clients to make requests
to Component Services for a component, which is hosted by Component Services
on behalf of the client; thus, the client’s method calls and data are marshaled byComponent Services
In order to be able to install a NET component in Component Services, youneed to have a reference to the System.EnterpriseServices.dll library as well as importthe System.EnterpriseServices namespace This namespace provides the main classes,interfaces, and attributes for communicating with Component Services The System.EnterpriseServices namespace gives us the ContextUtil class that is used in order for
an object to participate in transactions and interact with the security informationrelating to the object The ServicedComponent class is what gives the NET componentthe ability to be hosted in Component Services All NET component classes thatare to be hosted within Component Services must inherit from this class
There are also numerous attributes, classes, and method attributes defined in
2 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
Composite Default screen
Trang 3Component Services 3
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
Chapter 3
Transactions
A transaction is defined as a group of operations that either completes as a whole
(commits) or returns all operations to the state prior to the transaction (rolls back) if
it fails to complete Transactions are described as an all-or-nothing workflow
Components in the Component Services environment have the ability to participate
in transactions by voting on the outcome of the operations The voting is performed
by the code of the component calling methods that signify successful completion orfailure of the process the component performs When a component is instantiated inComponent Services, the component’s participation in transactions can be found inthe Transaction attribute The following list describes the possible values for theTransaction attribute:
■ Disabled The class will not use transactions and will ignore anytransactions from the parent object
■ NotSupported The class will not be instantiated within the context of atransaction
■ Required The class requires a transaction If no transaction exists, one will
The <Transaction()> attribute must be set to Required, RequiresNew,
or Supported for the component to be able to vote on the transaction outcome.
The following code segment shows how to use the Transaction attribute:
Trang 44 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
The class needs a means of voting on the outcome of the transaction This is done
by using methods of the ContextUtil object The following methods are used to vote
on the transaction:
■ SetAbort( ) Vote for failure of the transaction If any part of the transactioncalls SetAbort() and votes for a failure, the object is destroyed at the return ofthe method call
■ SetComplete( ) Vote for success of the transaction In this instance, theobject is destroyed at the return of the method call
■ EnableCommit( ) Vote for success of the transaction The object will not be
destroyed after the method call, allowing us to keep state across method calls
■ DisableCommit( ) Vote for the unsuccessful completion of the transaction.The object will not be destroyed after the return of the method call
The object is deactivated if you callSetComplete()orSetAbort() If you need to keep state (maintain an active object) between calls to the object, useEnableCommit()orDisableCommit()instead.
The following code sample shows how to use the transaction methods:
Public Sub Debit(ByVal id As Long, ByVal amount As Decimal) Try
' Update the account
… ' Signal success by calling SetComplete() ContextUtil.SetComplete()
Catch e As Exception ' Signal failure by calling SetAbort() ContextUtil.SetAbort()
' Pass the exception to the caller Throw e
End Try End Sub
This code segment can be rewritten by using the AutoComplete attribute of themethod as in this code segment:
<AutoComplete()>Public Sub Debit(ByVal id As Long, ByVal amount As Decimal) Composite Default screen
Trang 5Object pooling allows a preset number of objects to be created in advance This way,
the objects are ready for the client when called for When a client requests an object,
it is taken from the pool of available objects, and when the client request is finished,the object is returned to the pool
The object pool will improve the performance for objects that require large amounts
of processing time to create and bind to resources during creation of the object
To enable object pooling, you use the ObjectPooling attribute—this attribute hastwo parameters that control the initial size of the pool as well as the maximum size
■ MinPoolSize Controls the initial size of the pool
■ MaxPoolSize Sets the maximum number of objects that can be created inthe pool.If the number of objects in the pool has reached the MaxPoolSizevalue and additional requests for objects are received, the requests will bequeued until objects are made available
Always set a MaxPoolSize if you enable pooling That way, the server will not
be affected by a client application that keeps requesting more objects.
The return of objects to the object pool is controlled by the CanBePooled()method If your object supports object pooling and can safely be returned to thepool, return True; if not, return False
The following code segment illustrates the use of the ObjectPooling attribute:
<ObjectPooling(Enabled:=True,MinPoolSize:=3,MaxPoolSize:=42)> _ Public Class Savings
Inherits ServicedComponent Public Function GetBalance() As Decimal
End Function Protected Overrides Function CanBePooled() As Boolean Return True
End Function End Class Composite Default screen
Trang 6Set the size of the pool to meet the expected number of concurrent accesses
to the object.
Constructor Strings
One issue with the Component Services environment is that there is no possibility
to take advantage of custom constructors—only the default constructor of the classwill be executed That means that you cannot take advantage of the ability to passvalues to the constructor to initialize the instance To solve this problem, theConstruct() method provided in the ServicedComponent class gives us the ability topick up a string from the Component Service environment that is used during theconstruction phase
The ConstructionEnabled attribute indicates that the class is using the constructionstring from the Component Services environment By overriding the Construct()method, the class can be customized during instantiation The following code listingshows how to implement the Construct() method:
<ConstructionEnabled(True)> Public Class Savings Inherits ServicedComponent
Private strX As String Protected Overrides Sub Construct(ByVal s As String) ' This method is called by the Component Service after the ' constructor.
strX = s End Sub End Class
Figure 3-1 shows how the string is entered in the Component properties dialogfrom Component Services console:
There are additional methods that can be overridden from the ServicedComponentclass; these include Activate() and Deactivate() The Activate() method will be called
as the object is used from the pool, and the Deactivate() method is called every timethe object is returned to the pool
Use the Deactivate() method to clean up any changes to initialized members that might have taken place during the use of the object.
6 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
Composite Default screen
Trang 7Friend Function GetSharedProperty() As SharedProperty Dim bFlag As Boolean
Dim strValue As String Dim spm As New SharedPropertyGroupManager() Dim spg As SharedPropertyGroup
Dim sp As SharedProperty
'create a group called "Messages"
spg = spm.CreatePropertyGroup("Messages", PropertyLockMode.SetGet, _
PropertyReleaseMode.Process, bFlag) 'create a property called "History" for storing the event history
Trang 88 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
If bFlag = False Then 'if nothing exists, set default value sp.Value = ""
End If Return sp 'return the shared property object End Function
Use the Shared Property Manager whenever there is a need for serviced components in the same application to share data.
Component Services
Component Services is managed through the Components Services console from theAdministrative Tools folder (Start | Settings | Control Panel | Administrative Tools |Component Services) The console is shown next
The console is also used to read and manage the event log as well as the servicesrunning on a computer By expanding Components Services in the left panel, youwill see a Computers folder that lists the computers this console can manage
Expand Computers and then My Computer and then COM+ Applications to seethe installed component applications
Each application contains the components that make up that particularapplication To view these components, expand System Application and thenComponents as shown in Figure 3-2
If a component is in use, the icon in the right panel will rotate to indicate that thecomponent is running
You can right-click any of the objects to display a context menu that includes,among other things, a menu to the properties of the object It is through thisproperties dialog that you can modify the settings for the component
Composite Default screen
Trang 9■ ApplicationName This attribute is used to specify the application that thecomponent will be installed in.
■ Description Sets the description of the Component Services application
■ ApplicationActivation Specifies whether the Component Services application
is implemented as a library or server application A library application will workonly with clients on the local computer When the client requests the object, itwill execute outside of Component Services The server activation manages theexecution of the component in Component Services
■ AssemblyKeyFile Set this attribute to the file that contains the strong-namekey pair generated by the sn.exe utility
The following is a sample of how to set these attributes in the AssemblyInfo.vb file:
<Assembly: ApplicationName("Masiw Components")>
<Assembly: Description("VB NET Vineyard Components")>
Trang 1010 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
Once the assembly is built, it must be registered—yes, you heard right, you need
to register the assembly in the Registry The Component Services environment isstill the old COM environment, so you must comply with its rules by entering therelevant information in the Registry to make our component available To that end,the NET Framework ships with a utility—Regsvcs.exe—that eases registration Toregister an application, use the following syntax:
Regsvcs.exe myApplication.dll
The result is that the components in the myApplication.dll library are registered
in the Registry and installed in Component Services Regsvcs.exe verifies that there is
no entry for the components in the Registry before performing the registration, and
if there is a preexisting entry, the existing entry will be deleted This ensures that youhave only current information in the Registry
The Windows Registry is very much a part of Component Services, but through the use of Regsvcs.exe you do not have to directly edit the Registry.
To be on the safe side when updating components, I usually delete the application in the Component Services console before reinstalling,
When all the components in the assembly are registered in Component Services,you can optionally defer the registration until the first time a client applicationrequests a component that inherits from ServiceComponent This is calledautomatic registration
Now that you have covered the theory of serviced components, it is time to startbuilding and using them
Composite Default screen
Trang 11Build a Serviced Component 11
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
Chapter 3
CERTIFICATION OBJECTIVE 3.02
Build a Serviced Component
You will build a serviced component that highlights the use of the object pool
EXERCISE 3-1
Build the Serviced Component
1 Create a new Visual Basic NET project based on a Class Library template
Name the project PoolComponent:
Composite Default screen
Trang 1212 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
2 After the project is created, delete the Class1.vb file
3 Add a new Class file, naming it Pool.vb.
4 Add a new Class file, naming it NPool.vb.
5 Add a new Class file, naming it Util.vb The Solution Explorer should
resemble this image after the Class files are created:
Composite Default screen
Trang 13CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
7 Open the Util.vb source file
8 Import the following namespaces: System.EnterpriseServices and System.Runtime.InteropServices These namespaces give us support for ComponentServices as well as COM interfaces
9 Define the Utils class as follows:
Imports System.EnterpriseServices Imports System.Runtime.InteropServices
<ClassInterface(ClassInterfaceType.AutoDual)> _ Public Class Utils
Inherits ServicedComponent
End Class
The attribute declares the class to have a dual COM interface so thatthe component can be use by clients built with Visual Basic 6.0 orVBScript
10 In the Util class, define a method named GetHistory() as shown in thiscode segment:
'use the shared property manager to retrieve current event history Public Function GetHistory() As String
Dim strValue As String Dim sp As SharedProperty = GetSharedProperty() strValue = sp.Value
sp.Value = "" 'clear report string Return strValue
End Function
The GetSharedProperty() method is defined further down in this exercise; itreturns a reference to the shared property for this component
11 Declare a module named modUtil, and place it after the class definition for
the Utils class
Build a Serviced Component 13
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
Chapter 3
Composite Default screen
Trang 1412 In the modUtil module, declare a function named GetSharedProperty() thatreturns a SharedProperty Mark the function as a friend The code shouldlook this way:
Module modUtil Friend Function GetSharedProperty() As SharedProperty Dim bFlag As Boolean
Dim spm As New SharedPropertyGroupManager() Dim spg As SharedPropertyGroup, sp As SharedProperty
The GetSharedProperty() method will return a reference to the same sharedproperty for every call This way, you have a means of sharing this propertybetween multiple instances of the same class
Next you will implement the Pool class:
13 Open the Pool.vb file in the editor
14 Import the System.EnterpriseServices and System.Runtime.InteropServicesnamespaces
15 Define the Pool class as follows:
<Transaction(TransactionOption.Required), _ ClassInterfaceAttribute(ClassInterfaceType.AutoDual), _ ObjectPooling(Enabled:=True, MinPoolSize:=5, MaxPoolSize:=42), _ ConstructionEnabled(True)> _
Public Class Pool Inherits ServicedComponent
End Class
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
14 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
Composite Default screen
Trang 15Build a Serviced Component 15
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
Chapter 3
The attributes define this class to require transactions, to support a dualCOM interface, to have pooling enabled with a minimum number of objectsset to 5 and the maximum to 42, and to have the constructor string enabled
16 Declare a private string variable in the Pool class, naming the variable strX.
17 Declare a private sub method AddToSharedProperty(ByVal strY As String)
to the Pool class Add code to the method as follows:
Private Sub AddToSharedProperty(ByVal strY As String) 'get the "History" shared property
Dim sp As SharedProperty = GetSharedProperty() sp.Value = sp.Value.ToString & "Pool-" & strY & "(" & strX & ")" & vbCrLf End Sub
This method gets a reference to the shared property and appends theparameter to that property
18 Declare a default constructor, and call the AddToSharedProperty() methodwith a string to indicate that the constructor executed
Public Sub New() AddToSharedProperty("Constructor") End Sub
19 Declare a Construct() method It should be protected and overridden fromthe ServicedComponent base class Assign the parameter to the strX variable,and call the AddToSharedProperty() method to indicate that Construct()executed
Protected Overrides Sub Construct(ByVal s As String) strX = s
AddToSharedProperty("Contruct") End Sub
20 Declare a protected overridden CanBePooled() method Call theAddToSharedProperty() method to indicated you were called and return True
Protected Overrides Function CanBePooled() As Boolean AddToSharedProperty("CanBePooled")
Return True End Function Composite Default screen
Trang 1616 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
22 Declare a public function FtoC(byval f As Decimal) As Decimal that returnsthe temperature in Celsius given that f is in Fahrenheit Mark the function
to be AutoComplete Call AddToSharedProperty() to indicate the methodwas called
<AutoComplete()> Public Function FtoC(ByVal f As Decimal) As Decimal Return (f - 32) * 5 / 9
AddToSharedProperty("FtoC") End Function
23 Implement the Activate() and Deactivate() overridden methods, callingAddToSharedProperty() in each method to indicate you were there
Protected Overrides Sub Activate() AddToSharedProperty("Activate") End Sub
Protected Overrides Sub Deactivate() AddToSharedProperty("DeActivate") End Sub
Next you will implement the NPool class To perform this action, you willcopy methods from the Pool class, as the functions will be the same exceptfor the pooling behavior
24 Open the NPool.vb source file in the editor
25 Import the System.EnterpriseServices and System.Runtime.InteropServicesnamespaces
26 Define the NPool class to require transactions, support the dual COMinterface, support Construction strings, and not support object pooling
Composite Default screen
Trang 17Build a Serviced Component 17
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
Chapter 3
Public Class NPool Inherits ServicedComponent
End Class
27 Declare a private string variable in the NPool class; name the variable strX.
28 Copy the following methods from the Pool class to the NPool class:
Activate(), Deactivate(), CtoF(), FtoC(), New(), AddToSharedProperty(),and Construct()
29 Change the AddToSharedProperty() method to identify the NPool class
Private Sub AddToSharedProperty(ByVal strY As String) 'get the "History" shared property
Dim sp As SharedProperty = GetSharedProperty() sp.Value = sp.Value.ToString & "No Pool-" & strY _
& "(" & strX & ")" & vbCrLf End Sub
30 Save and build the component, resolving any build errors
In order for us to be able to register the component, you will need to create astrong-name key file and add it to the assembly
EXERCISE 3-2
Create a Strong-Name key
1 Open the PoolComponent project
2 Start a Visual Studio NET Command Prompt Click Start | Programs |Microsoft Visual Studio NET | Visual Studio NET Tools | Visual Studio.NET Command Prompt
3 Change directory to the location of the PoolComponent project(C:\VB\PoolComponent)
4 Use the strong-name utility (sn.exe) to generate the strong-name key for thecomponent
C:\>cd \VB\PoolComponent C:\VB\PoolComponent>sn -k PoolComponent.snk
Microsoft (R) NET Framework Strong Name Utility Version 1.0.3705.0
Composite Default screen
Trang 1818 Chapter 3: Creating and Managing Microsoft Windows–Serviced Components
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind /
222653-6 / Chapter 3
Copyright (C) Microsoft Corporation 1998-2001 All rights reserved.
Key pair written to PoolComponent.snk C:\VB\PoolComponent>
5 Switch back to Visual Studio NET
6 Open the AssemblyInfo.vb file in the editor
7 Import the System.EnterpriseService namespace
8 Add the following assembly attributes:
<Assembly: ApplicationActivation(ActivationOption.Server)>
<Assembly: ApplicationName("Pool Component")>
<Assembly: Description("Study Guide serviced component exercise")>
<Assembly: AssemblyKeyFile("PoolComponent.snk")>
9 Save the project
10 On the Build menu, click the Build Solution
11 Close Visual Studio NET
After building the serviced component, you needs to register it to make itavailable in Component Services To do this:
12 Return to the Visual Studio NET command prompt, or open a new one
13 Navigate to the directory where the PoolComponent.dll component islocated (C:\VB\PoolComponent\bin)
14 Execute the Regsvcs.exe command to register the component
C:\VB\PoolComponent\bin>Regsvcs.exe PoolComponent.dll Microsoft (R) NET Framework Services Installation Utility Version 1.0.3705.0 Copyright (C) Microsoft Corporation 1998-2001 All rights reserved.
Installed Assembly:
Assembly: C:\VB\PoolComponent\bin\PoolComponent.dll Application: Pool Component
TypeLib: c:\vb\poolcomponent\bin\PoolComponent.tlb
C:\VB\PoolComponent\bin>
Composite Default screen
Trang 19Build a Serviced Component 19
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic NET / Lind / 222653-6 /
Chapter 3
15 To configure the Pool component, open the properties for the PoolComponent.Pool component and select the Activation tab Enable the constructor string
to be “Pooled:” as shown here:
Composite Default screen