![]() |
Languages »
VB.NET »
General
Beginner
Serviced Components in VB.NETBy SaravanakThis article explains how to develop and deploy serviced components in Visual Basic .NET. It also explains about custom attributes which is used in COM+ services. |
VB.NET 1.0, Win2K, WinXP, Visual Studio, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||
.NET is Microsoft's next-generation component technology. It is designed from the ground up to simplify component development and deployment, as well as to support interoperability between programming languages. Despite its innovations and modern design, .NET is essentially a component technology. Like COM, .NET provides you with the means to rapidly build binary components, and Microsoft intends for .NET to eventually succeed COM. Like COM, .NET does not provide its own component services. Instead, .NET relies on COM+ to provide it with instance management, transactions, activity-based synchronization, granular 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. A .NET component that uses COM+ services is called a serviced component to distinguish it from the standard managed components in .NET.
A .NET component that takes advantage of COM+ services needs to derive from the .NET base class ServicedComponent. ServicedComponent is defined in the System.EnterpriseServices namespace. To develop a simple serviced component following steps have to be followed:
ServicedComponent class. For example, the following code ensures that the MyClass class is hosted by a COM+ application: Imports System.EnterpriseServices
Public Class MyClass Inherits ServicedComponent
Imports System.EnterpriseServices
<Transaction(TransactionOption.Required)> _
Public Class MyClass Inherits ServicedComponent
<AutoComplete()>
Public Sub DoSomething()
End Sub
End Class
After a serviced component is registered, clients can create instances of the component the way they create instances of any other component.
There are two ways to configure a serviced component to use COM+ services. The first is COM-like: you derive from ServicedComponent, add the component to a COM+ application, and configure it there. The second way is to apply special attributes to the component, configuring it at the source-code level. When the component is added to a COM+ application, it is configured according to the values of those attributes. Attributes are discussed in greater detail below.
.NET allows you to apply attributes to your serviced components with great flexibility. If you do not apply your own attributes, a serviced component is configured using default COM+ settings when it is added to a COM+ application. You can apply as many attributes as you like. A few COM+ services can only be configured via the Component Services Explorer. These services are mostly deployment-specific configurations, such as persistent subscriptions to COM+ events and allocation of users to roles. In general, almost everything you can do with the Component Services Explorer can be done with attributes. It is recommended that you put as many design-level attributes as possible (such as transaction support or synchronization) in the code and use the Component Services Explorer to configure deployment-specific details.
A serviced component is hosted by a COM+ application and must be accessible to that application. For accessibility, serviced components have the following registration and configuration requirements:
You can perform that registration in three ways:
Regardless of the technique you use, the registration process adds your serviced components to a COM+ application and configures them according to the default COM+ settings or according to their attributes (if present in the code). If the assembly contains incompatible attributes, the incompatibility is detected during registration and the registration is aborted. Future versions of the .NET compilers may detect incompatibilities during compilation time.
To register your component manually, use the RegSvcs.exe command-line utility. RegSvcs accepts as a parameter, the name of the file containing your assembly's metadata. In a single DLL assembly, that file is simply the assembly file. If you do not specify as an assembly attribute the name of the COM+ application that should host your components, RegSvcs must be told that name explicitly as a command-line parameter, using the /appname: switch.
For example, if your single DLL assembly resides in MyAssembly.dll and you wish to add the serviced components in that assembly to the MyApp COM+ application, you would use RegSvcs in this manner:
RegSvcs.exe /appname: MyApp MyAssembly.dll
The command-line application name is ignored if the assembly contains an application name.
If you don't specify a COM+ application name, either in the assembly or as a command-line parameter, RegSvcs uses the assembly name for the application name. If your assembly is called MyAssembly, RegSvcs adds the components to the MyAssembly COM+ application. This behavior is the same for all the command-line switches.
When RegSvcs adds a serviced component to the COM+ Catalog, it must give it a class-ID (CLSID) and a prog-ID. RegSvcs creates a GUID for every component (based on the assembly's version and the class definition) and names it < Namespace>.<Component name>. You can also specify the CLSID and the prog-ID of your serviced components using attributes.
In addition to adding the serviced components in the assembly to a COM+ application, RegSvcs creates a type library. This library contains interface and CoClass definitions to be used by unmanaged clients (COM clients). The default type library filename is <Assembly name>.tlb--the name of the assembly with a .tlb extension.
When a managed client creates a serviced component, the .NET runtime resolves which assembly version to use for that client. Next, the runtime verifies that the required version is registered with COM+. If it is not registered, the runtime installs it automatically. This process is called dynamic registration. As with RegSvcs, if the assembly contains an application name, then that name is used; if it does not, then the assembly's name is used for the COM+ application's name.
Note that only .NET clients can rely on having dynamic registration done when they instantiate a .NET serviced component. For COM clients, you must use the RegSvcs utility. Another limitation of dynamic registration is that serviced components in the assembly are configured according to the attributes in the assembly and the COM+ defaults. If you require configuring some services (such as events subscriptions) using the Component Services Explorer for your application to function properly, you must use RegSvcs to register your components and provide the additional configuration using the Component Services Explorer. Only then can clients use your serviced components. As a result, dynamic registration is only useful for serviced components that contain all the service configurations they need in their code through the use of attributes. Finally, dynamic registration requires that the user invoking the call that triggers dynamic registration be a member of the Windows 2000 Administrators group. It has this requirement because dynamic registration makes changes to the COM+ Catalog; if the user invoking it is not a member of the Windows 2000 Administrators group, dynamic registration will fail.
In general, you should use RegSvcs and the Component Services Explorer rather than relying on dynamic registration. If you want to rely on dynamic registration of your serviced components, you should increment the version number of your assembly every time you make a change to one of the components' attributes, to ensure that you trigger dynamic registration.
Both RegSvcs and dynamic registration use a .NET class called RegistrationHelper to perform the registration. RegistrationHelper implements the IRegistrationHelper interface, whose methods are used to register and unregister assemblies. For example, the InstallAssembly( ) method registers the specified assembly in the specified COM+ application (or the application specified in the assembly). This method is defined as:
Public Sub InstallAssembly( _
ByVal assembly As String, _
ByRef application As String, _
ByRef tlb As String, _
ByVal installFlags As InstallationFlags _
)
The installation flags correspond to the various RegSvcs switches. See the MSDN Library for additional information on RegistrationHelper.
You can provide .NET with an assembly attribute, specifying the name of the COM+ application you would like your components to be part of, by using the ApplicationName assembly attribute:
<Assembly: ApplicationName("MyApplication")>
If you do not provide an application name, .NET uses the assembly name. The ApplicationName attribute (and the rest of the serviced components attributes) is defined in the System.EnterpriseServices namespace. You must add this namespace to your project references and reference that namespace in your assembly information file:
imports System.EnterpriseServices;
Every COM+ application has a GUID identifying it called the application ID. You can provide an assembly attribute specifying the application ID in addition to the application name:
<Assembly: ApplicationID("8BE192FA-57D0-49a0-8608-6829A314EEBE")>
Unlike the application name, the application ID is guaranteed to be unique, and you can use it alongside the application name. Once an application ID is specified, all searches for the application during registration are done using the application ID only, and the application name is only useful as a human-readable form of the application identity.
Instead of having the registration process generate a CLSID for your serviced component, you can specify one for it using the Guid attribute:
imports System.EnterpriseServices;
<Guid ("260C9CC7-3B15-4155-BF9A-12CB4174A36E")> Public Class MyCls
Inherits ServicedComponent
'Code Here
End Class
The Guid attribute is defined in the System.Runtime.InteropServices namespace.
When you specify a class ID, subsequent registrations of the assembly don't generate a new CLSID for the component, regardless of the version of the assembly being registered. Registrations always reconfigure the same component in the COM+ Catalog. Specifying a class ID is useful during development, when you have multiple cycles of code-test-fix. Without it, every invocation by the test client triggers a dynamic registration--you very quickly clutter the COM+ application with dozens of components, when you actually only use the latest one.
Instead of having the registration process generate a name for your serviced component (namespace plus component name), you can specify one for it using the ProgID attribute:
imports System.EnterpriseServices;
<ProgId("MyClass.Web")> Public Class MyCls
Inherits ServicedComponent
'Code Here
End Class
The ProgId attribute is defined in the System.Runtime.InteropServices namespace.
To specify the COM+ application's activation type, you can use the ApplicationActivation assembly attributes. You can request that the application be a library or a server application:
<assembly: ApplicationActivation(ActivationOption.Server)>
or:
<assembly: ApplicationActivation(ActivationOption.Library)>
If you do not provide the ApplicationActivation attribute, then .NET uses a library activation type by default. Note that this use differs from the COM+ default of creating a new application as a server application
The Description attribute allows you to add text to the description field on the General Properties tab of an application, component, interface, or method. After registration, the assembly-level description string becomes the content of the hosting COM+ application's description field; the class description string becomes the content of the COM+ component description field. The interface and method descriptions are mapped to the corresponding interface and method in the Component Services Explorer.
The ObjectPooling attribute is used to configure every aspect of your component's object pooling. The ObjectPooling attribute enables or disables object pooling and sets the minimum or maximum pool size and object creation timeout. For example, to enable object pooling of your component's objects with a minimum pool size of 3, a maximum pool size of 10, and a creation timeout of 20 milliseconds, you would write:
<ObjectPooling(MinPoolSize=3,MaxPoolSize=10,CreationTimeout=20)>
Public Class MyClass
Inherits ServicedComponent
'Code Here
End Class
The MinPoolSize, MaxPoolSize, and CreationTimeout properties are public properties of the ObjectPooling attribute class. If you do not specify values for these properties (all or just a subset) when your component is registered, the default COM+ values are used for these properties (a minimum pool size of 0, a maximum pool size of 1,048,576, and a creation timeout of 60 seconds).
Any COM+ configured component that implements the IObjectConstruct interface has access during construction to a construction string, configured in the Component Services Explorer. Serviced components are no different. The base class, ServicedComponent, already implements the IObjectConstruct interface as a virtual method (it has only one method). Your derived serviced component can override the Construct( ) method, as shown in this code sample:
Public Class Web
Inherits ServicedComponent
Protected Overrides Sub Construct( _
ByVal constructString As String)
If Not constructString Is Nothing Then
mstrConstructionString = constructString
End If
End Class
The MinPoolSize, MaxPoolSize, and CreationTimeout properties are public properties of the ObjectPooling attribute class. If you do not specify values for these properties (all or just a subset) when your component is registered, the default COM+ values are used for these properties (a minimum pool size of 0, a maximum pool size of 1,048,576, and a creation timeout of 60 seconds).
If the checkbox "Enable object construction" on the component activation tab is selected, then the Construct( ) method is called after the component's constructor, providing it with the configured construction string.
You can also enable construction string support and provide a default construction string using the ConstructionEnabled attribute:
<ConstructionEnabled(Enabled=true, Default = "My String")>
Public Class Web
Inherits ServicedComponent
End Class
The ConstructionEnabled attribute has two public properties. Enabled enables construction string support for your serviced component in the Component Services Explorer (once the component is registered) and Default provides an initial string value. When your component is registered with COM+, the registration process assigns the default string to the constructor string field on the component activation tab. The default string has no further use after registration. New instances of your component receive as a constructor string, the current value of the constructor string field. For example, if the default string is String A, when the serviced component is registered, the value of the constructor string field is set to String A. If you set it to a different value, such as String B, new instances of the component get String B as their construction string. They receive the current value, not the default value.
You can configure your serviced component to use the five available COM+ transaction support options by using the Transaction attribute. The Transaction attribute's constructor accepts an enum parameter of type TransactionOption, which has following five values
Disabled
NotSupported
Supported
Required
RequiresNew For example, to configure your serviced component to require a transaction, use the TransactionOption.Required value:
<Transaction(TransactionOption.Required)> Public Class Web Inherits ServicedComponent End Class
A strong name consists of the assembly's identity---it's simple text name, version number, and culture information (if provided)---plus a public key and a digital signature. It is generated from an assembly file (the file that contains the assembly manifest, which in turn contains the names and hashes of all of the files that make up the assembly), using the corresponding private key. Once an assembly is created, you cannot sign it with a strong name. To create a strong-named assembly, you must sign it with a strong name when you create it.
For creating a strong named assembly, you need to create a cryptographic key pair using the Strong Name tool (Sn.exe) and assign that key pair to the assembly using either a command-line compiler or the Assembly Generation tool (Al.exe). The .NET Framework SDK provides both Sn.exe and Al.exe.
At the command prompt, type the following command:
sn �k <file name>
In this command, file name is the name of the output file containing the key pair. The following example creates a key pair called sgKey.snk.
sn -k sgKey.snk
There are two ways to sign an assembly with a strong name:
AssemblyKeyFile attribute or the AssemblyKeyName attribute, depending on where the key file to be used is located. At the command prompt, type the following command:
al /out:<assembly name> <module name> /keyfile:<file name>
In this command, assembly name is the name of the assembly to sign with a strong name, module name is the name of the code module used to create the assembly, and file name is the name of the container or file that contains the key pair.
The following example signs the assembly MyAssembly.dll with a strong name using the key file sgKey.snk.
al /out:MyAssembly.dll MyModule.netmodule /keyfile:sgKey.snk
In a code module, add the AssemblyKeyFile attribute or AssemblyKeyName attribute specifying the name of the file or container that contains the key pair to use to sign the assembly with a strong name. The following code example uses the AssemblyKeyFile attribute with a key file called sgKey.snk.
When an assembly that uses ApplicationActivationOption is set to server, the assembly is loaded by dllhost.exe, which most likely is not in the same directory as the client. Assemblies that use serviced components in COM+ server apps should be placed in the GAC. Assemblies that use serviced components in COM+ libraries apps may not need to be placed in the GAC (unless they are located in different directories). The only exception is when hosting with ASP.NET�assemblies should not be placed in the GAC to enable shadow copy to operate correctly. So it is better to place all serviced components inside the GAC.
There are two ways to install an assembly into the Global Assembly Cache:
This is the recommended and most common way to add assemblies to the Global Assembly Cache. The installer provides reference counting of assemblies in the Global Assembly Cache and other benefits.
You can use Gacutil.exe to add strong-named assemblies to the Global Assembly Cache. This tool can also be used to view the contents of the Global Assembly Cache.
At the command prompt, type the following command:
gacutil �i <assembly name>
In this command, assembly name is the name of the assembly to install in the Global Assembly Cache. The following example installs an assembly with the file name hello.dll into the Global Assembly Cache.
gacutil -i hello.dll
This article explains how to develop and deploy serviced components in Visual Basic .NET. It also explains about custom attributes which is used in COM+ services.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 13 Apr 2003 Editor: Smitha Vijayan |
Copyright 2003 by Saravanak Everything else Copyright © CodeProject, 1999-2009 Web11 | Advertise on the Code Project |