com+.net

click here to download

Using
COM+ Services in .NET









Summary:
Add new Microsoft .NET components to existing COM and COM+
applications and they will be able to work together; this will help
you if you need to develop a .NET application that can do things like
participate in transactions, take advantage of role-based security,
or interact with a queue.


Objectives



  • Learn
    about using COM+ Services in Microsoft® .NET.


  • Create
    a serviced component.


  • Deploy
    a serviced component.



Assumptions



The following should be
true for you to get the most out of this document:



  • You
    have used Microsoft Transaction Server (MTS) and distributed
    transactions in Microsoft Visual Basic® 6.0.


  • You
    have used role-based security with COM+ Services.


  • You
    have created and used queues in COM+ Services.


  • You
    are very familiar with .NET classes.


  • You
    are familiar with creating console applications in .NET.



Contents



Using COM+ Services in
.NET
Developing Transaction-Based Components
Role-Based
Security
Using Queued Components
What's Different in COM+ Since
Visual Basic 6.0?
Summary


Using
COM+ Services in .NET



You probably have used
COM+ Applications to host components that you have written in Visual
Basic or C++. COM+ offers many valuable services, such as
transactions, queued components, just-in-time activation, role-based
security, shared properties, etc. One of the main attractions of
using COM+ to host components was that you could change the way the
component behaved without having to write any code, such as marking a
component's transaction support as Required. By setting a radio
button on your COM+ component from within the Component Services MMC
snap-in, every time your component is created, it is created in the
context of a COM+ transaction. When a component uses COM+
transactions, any database transactions are handled by the
Distributed Transaction Coordinator (DTC). Figure 1 shows an example
of setting the Required Transaction option from within the Component
Services interface.





Figure
1. Sample COM+ component that requires a transaction



Setting the security
for your component is just as easy as setting the transaction
support. You can choose which users can run which components, and
even which methods, without recompiling your code. You choose by
using the COM+ Services snap-in.


.NET
Can Use All COM+ Services



In the .NET Framework,
you can still use all of the services that COM+ offers, as long as
your classes derive from the
System.EnterpriseServices.ServicedComponent class. Any class that
derives from the ServicedComponent class will be hosted by COM+
services and can use any of the available COM+ services. Table 1
shows all of the COM+ services supported in .NET, as well as a short
description of each service.



Table
1. COM+ services available


























































COM+
Service



Description



Automatic
Transaction Processing



Applies
declarative transaction-processing features



COM
Transaction Integrator (COMTI)



Encapsulates
CICS and IMS applications in Automation objects



Compensating
Resource Managers (CRMs)



Applies
atomicity and durability properties to non-transactional resources



Just-In-Time
Activation



Activates
an object on a method call and deactivates when the call returns



Loosely
Coupled Events



Manages
object-based events



Object
Construction



Passes
a persistent string value to a class instance on construction of
the instance



Object
Pooling



Provides
a pool of ready-made objects



Queued
Components



Provides
asynchronous message queuing



Role-Based
Security



Applies
security permission based on role



Shared
Properties



Shares
state among multiple objects within a server process



Synchronization
(Activity)



Manages
concurrency



XA
Interoperability



Supports
the X/Open transaction-processing model



Reasons
to Use COM+ Services in .NET



If you will be writing
a .NET application that needs to be able to do things like
participate in transactions, take advantage of role-based security,
or interact with a queue, you will use the COM+ services offered in
.NET. .NET makes these services easy to implement, as you will learn
in this document.



Tip   If
you do not need your .NET code to work with COM+ services, that is,
you are only going to be working in the .NET Framework, do not use
System.EnterpriseServices, because there is a performance penalty.


Overview
of COM+ Component Development



When creating
components in .NET that you want to interact with COM+ Services, you
perform the following steps. Table 2 includes an explanation of each
step.




  1. Create a Class
    Library.


  2. Create
    all classes so they inherit from the
    System.EnterpriseServices.ServicedComponents class.


  3. Create
    an assembly.


  4. Create
    a strong name.




Table
2. Definition of terms used in creating a .NET component





























Term



Description



Class
Library



A
.dll project type that contains classes. There is generally no
user interface with this type of project.



System.EnterpriseServices.ServicedComponents



A
class in the .NET Framework that is required for you to be able
to interact with COM+ Services



Assembly



A
description of all of the classes and interfaces within your
project



Strong
Name



Generates
a GUID from your assembly so that your component can be
registered with COM+ Services




Developing
Transaction-Based Components



In the first part of
this document, you will learn to create a .NET component that uses
the transactional services of COM+. You will learn how to write both
the component and the front-end application that interacts with this
component.


Creating
a COM+ Transaction Component



There are a few steps
that you need to go through to get a .NET component to run under COM+
services. To begin, you have to create a class that derives from the
System.EnterpriseServices.ServicedComponent class. This base class
gives you all of the appropriate methods and properties needed to
interact with COM+ services. You need to mark the class as requiring
a new transaction, and mark any methods you create as able to
automatically complete the transaction if no errors occur. Let's try
it.




  1. Open Microsoft Visual
    Studio® .NET and create a new project as a ClassLibrary project.


  2. Rename
    the Class1.vb file to COMPlusServices.vb.


  3. Open
    the COMPlusServices.vb file and change the class name from Class1 to
    COMPlusServices.


  4. Type
    in the code shown below into this new class.



  5. Imports
    System.EnterpriseServices



  6. Imports
    System.Reflection





  7. '********************************************



  8. 'COM+ Registration
    details





  9. 'Supply the COM+
    application name



  10. <Assembly:
    ApplicationNameAttribute("ComPlusExample")>





  11. 'Supply a strong-name
    assembly



  12. <Assembly: _



  13. AssemblyKeyFileAttribute("bin/ComPlusExample.snk")>



  14. '********************************************





  15. <TransactionAttribute(TransactionOption.Required)>
    _



  16. Public Class
    COMPlusServices



  17. Inherits
    ServicedComponent





  18. Public Sub New()



  19. MyBase.New()



  20. End Sub





  21. <AutoComplete()>
    Public Function DoTransaction() _



  22. As String



  23. Return "Success
    with COM+"



  24. End Function




End Class



This code starts out by
importing a couple of namespaces to eliminate some typing when
declaring components.




  1. Next are COM+
    registration details. Enter the following line of code:



  2. 'Supply the COM+
    application name




<Assembly:
ApplicationNameAttribute("ComPlusExample")>



This line assigns the
ApplicationNameAttribute a value of ComPlusExample. This is what the
name of the COM+ application will be when it is registered in the
COM+ Catalog. After the first time this component is called, when you
go into the COM+ Applications folder in the MMC snap-in, you will see
this as the application name.



The next part of the
code declares the AssemblyKeyFileAttribute attribute:



<Assembly: _



AssemblyKeyFileAttribute("bin/ComPlusExample.snk")>



This informs the COM+
catalog where the information about the strong name is located. You
will create the .SNK file in a later step, but it is the file that
describes the component to COM+.



You will now finally
declare the Class name, COMPlusServices, using the following code.



<TransactionAttribute(TransactionOption.Required)>
_



Public Public Class
COMPlusServices



The attribute in front
of this class name informs COM+ that you wish to set the transaction
attribute to Required. Adding this line of code is the same as going
into the COM+ Applications snap-in, as shown in Figure 1, and setting
this attribute manually.



The next line of code
in the class inherits from the ServicedComponent within the
System.EnterpriseServices namespace.



Inherits
ServicedComponent



If you do not include
this line, you will be unable to make this component work under COM+.


Add
a Transaction Method



Now that the setup of
this class is complete, you can create a method that will actually do
something. The function DoTransaction in the code you wrote returns a
string value, but shows the syntax you must use to have this method
participate in a transaction.



<AutoComplete()>
Public Function DoTransaction() As String



Return "Success
with COM+"



End Function



It is important that
you prefix this method with the <AutoComplete()> attribute.
This means that as long as there is not an exception in this method,
SetComplete will be automatically called when this method finishes.
If there is an exception in the method, the .NET runtime
automatically calls the SetAbort method. This is different than
writing COM components in Visual Basic 6.0, where you had to
explicitly call SetComplete and SetAbort on your own.


Create
a Strong Name



Before compiling your
component, you need to give your assembly for this component a strong
name. If you do not do this, the COM+ Catalog will not recognize your
component and will not be able to register it. Actually, you have
already done this via the AssemblyKeyFile attribute that you used
earlier, but now you need to create the strong name and associate a
GUID with your assembly by using the Strong Name Tool (Sn.exe).




  1. Open a command prompt.


  2. To
    create the strong name, type the following at a command prompt and
    then press
    Enter.




sn -k ComPlusExample.snk




  1. Copy the
    ComPlusExample.snk file from the root folder of your hard drive
    (most likely C:/) into the bin directory under the folder where your
    project is.




You now need to compile
this program so it can build the necessary files needed to register
this component with COM+. In Visual Studio .NET, on the
Build
menu, click
Build.


Build
a Client Test Application



Now that you have built
your component, you need to build a client application to call this
component and test it out. Create a simple console application where
the module file's Main method creates an instance of your new
component, and calls the DoTransaction() method. Here are the main
steps.




  1. In Visual Basic .NET,
    create a new console application project.


  2. Add
    a reference to the component that you just created.


  3. Type
    in the code shown below.



  4. Module modMain



  5. Sub Main()



  6. Dim objCOMPlus
    As New _



  7. COMPlusJumpStart.COMPlusServices()





  8. Console.WriteLine(objCOMPlus.DoTransaction)



  9. Console.ReadLine()



  10. End Sub




End Module


Try
It Out



You are finally ready
to run this application and see it work.




  1. Open the Component
    Services MMC snap-in and verify that your component was dynamically
    registered into the COM+ Catalog. You should see something that
    looks like Figure 2.


  2. Compile
    and run the console application.






Figure
2. The new .NET serviced component in the COM+ Catalog



Role-Based
Security



When you have many
users making calls to COM components that run under COM+, you need to
verify that only specific people have access to certain components.
COM+ allows you to define roles and assign NT users to those roles.
Once these roles are in place, you can assign which roles can run
which components, and even which methods on those components can be
run.



Let's add a method to
this same COMPlusServices class to incorporate role-based security.
You will create a role called Managers, and in the new method, test
to see if the caller is in the Managers role.


Steps
to Add Role-Based Security



Instead of directly
modifying the COM+ application from the Component Services MMC
snap-in to add the security role, you will add a new attribute to
your project. You will use the SecurityRoleAttribute class to add the
new Managers role. The constructor for this class has two arguments:
role (string) and everyone (Boolean). The
role
argument specifies the name of the role to be created, and the
everyone argument
specifies whether or not the built-in Everyone group is added to the
users of the role.




  1. Add a new security
    role to the COM+ application by typing in the following code just
    below the comment COM+ Registration details.



  2. '********************************************



  3. 'COM+ Registration
    details





  4. 'Role-based security
    attribute




<Assembly:
SecurityRoleAttribute("Managers", False)>




  1. Change the security
    level setting to perform access checks at the process and component
    level. This enables the COM+ application to have a security call
    context.


  2. Bring
    up the COM+ Services snap-in.


  3. Click
    the
    Security
    tab and change the security level, as shown in Figure 3.






Figure
3. Setting the security level property in the COM+ Catalog




As an alternative to
the manual process, you could add an attribute to your component
telling it to perform access-level checks. Below is the code to add
within the COM+ Registration detail section at the top of your
COMPlusServices class.



<Assembly:
ApplicationAccessControlAttribute



(AccessChecksLevel:=AccessChecksLevelOption.ApplicationComponent)>


Check
for a Security Role



You will now add a new
method to the class called IsManager. This method will check to see
if the user is a member of the role Managers. This method is a
function and returns a Boolean value indicating whether or not the
caller is part of the Managers role. In order to get access to the
security context of the user calling the method, you need to use the
SecurityCallContext class. You get the current caller's context by
calling the CurrrentCall method. Then, you call the IsCallerInRole
method, and pass in Managers as the name of the role.




  1. Add the method shown
    below to the COMPlusServices class.



  2. Public Function
    IsManager() As Boolean





  3. Dim objCallContext
    As SecurityCallContext = _



  4. SecurityCallContext.CurrentCall






  5. IsManager = _



  6. objCallContext.IsCallerInRole("Managers")






End Function



You will now need to
rebuild the component to try out this new method.




  1. From the Visual Studio
    .NET
    Build
    menu, click
    Rebuild
    Solution
    .



Try
It Out




  1. Modify the code in the
    Sub Main() method of your console client application. Here is what
    the code should look like:



  2. Sub Main()





  3. Dim objCOMPlus As
    New _



  4. COMPlusJumpStart.COMPlusServices()






  5. Console.WriteLine(objCOMPlus.DoTransaction)



  6. Console.WriteLine(objCOMPlus.IsManager().ToString)



  7. Console.ReadLine()






End Sub




  1. Run the console
    application from the command prompt by typing in the name of the
    executable you compiled.




The first time you run
the code, you should get an exception stating that access was denied
because no users were added to the Managers role. To correct this,
add yourself as a user to Managers, and re-run the application. This
time, there should not be any exceptions. You could also add
exception handling to your code. Here is what your client should like
with the exception handling code:



Sub Main()








Try








Dim objCOMPlus As
New _



COMPlusJumpStart.COMPlusServices()








Console.WriteLine(objCOMPlus.DoTransaction)



Console.WriteLine(objCOMPlus.IsManager().ToString)



Console.ReadLine()








Catch objException As
Exception



Console.WriteLine("An
error occurred. " _



& "Details:
" _



&
objException.Message)



Console.ReadLine()








End Try








End Sub


Using
Queued Components



In COM+ applications,
it is easy to add queuing support. You just make sure that the
application is running as a server application (out of process), and
then you set its Queued and Listen properties on the Queuing tab.
Once these settings are made, client applications can call your
components asynchronously or synchronously. The beauty of this
feature is that you do not have to change the code in your COM
object; you just change its properties in the COM+ Catalog.



The .NET Framework
supports queued components, and as you might expect, you can give
your components queuing support by using attributes instead of
manually changing the COM+ Catalog.



Let's add a method to
the COMPlusServices class, and call it asynchronously using COM+
Queued Components services from a .NET client application.




  1. Make your COM+
    application a server application (out of process). This is a
    requirement for Queued Components. To do this via attributes, add
    the following code to your project:



  2. '********************************************



  3. 'COM+ Registration
    details






<Assembly:
ApplicationActivationAttribute(ActivationOption.Server)>




  1. Add queuing support to
    your component. Make it accessible to MSMQ queues, and make it
    listen to its own queue to process messages. Here is the code to do
    this via attributes:



  2. '********************************************



  3. 'COM+ Registration
    details





  4. <Assembly:
    ApplicationQueuingAttribute(Enabled:=True,




QueueListenerEnabled:=True)>




  1. Add a method to your
    class called QueueTest. Make sure that it is a subroutine; it cannot
    have a return value. Have it write a message to the Windows
    Application Log. Here is what the code should look like:



  2. Public Sub QueueTest()



  3. System.Diagnostics.EventLog.WriteEntry(_



  4. "COMPlusServces",
    "Queue Test", _



  5. Diagnostics.EventLogEntryType.Error)




End Sub



That's it. That is all
you have to do to enable your component to be a COM+ Queued
Component.


Try
It Out



You should now try out
this queued component by creating another console application and
calling this component.




  1. Create a new console
    application.


  2. Add
    the following code to the Sub Main procedure of this console
    application.



  3. Sub Main()



  4. Dim objTest As
    COMPlusJumpStart.COMPlusServices



  5. Dim strMoniker





  6. strMoniker = _



  7. "queue:/new:COMPlusJumpStart.COMPlusServices"



  8. objTest =
    GetObject(strMoniker)



  9. objTest.QueueTest()




End Sub



This asynchronously
calls the QueueTest method on your component. If you wanted to call
your method synchronously, you would call it like you have all of the
other methods in your component.



You can now run this
console application to try out this queued component.


What's
Different in COM+ Since Visual Basic 6.0?



There are many things
that you already know from Visual Basic 6.0 or COM that are the same
in .NET. But now you have the benefit of working within the .NET
Framework, which helps objects interact smoothly, with a minimum of
coding and maintenance on your part.



Typical of this sort of
streamlining, in Visual Basic 6.0, you had to explicitly call
SetComplete and SetAbort on your own. In .NET, the SetComplete and
SetAbort are called by the <AutoComplete()> attribute.



Another difference
between Visual Basic .NET and Visual Basic 6.0 is that Visual Basic
6.0 components can't make use of COM+ object pooling because they use
the Single Threaded Apartment threading model. Visual Basic .NET
components are .NET components and as such, support the Any Apartment
threading model and hence can make use of COM+ object pooling.


Summary



As you can see, the
.NET Framework makes it easy to take advantage of the services that
COM+ offers. This means that you can add new .NET components to
existing applications written with COM and COM+, and they will be
able to work together. This is very important, because it means that
you do not have to throw away all of your existing COM and COM+ code.
If you are building a new application from scratch, it is highly
recommended that you build it entirely in the .NET Framework, as it
will be much more efficient.









1









0 comments: