Using COM Enterprise Services


Using COM+ Enterprise Services

The System.EnterpriseServices namespace provides an important infrastructure for building enterprise applications. This namespace defines a set of attributes and supporting classes and interfaces that can be used to build applications that utilize services such as JIT Activation, Synchronization, Object Pooling, Distributed Transactions, and Shared Property Management.

Serviced Component

As a first step in utilizing COM+ services, you need to create what is called a ServicedComponent. A ServicedComponent inherits from the ServicedComponent class. This can be done either programmatically (as shown next) or by manually registering a .NET component into a COM+ application. Next , the component uses a set of attributes to set the various COM+ services. A ServicedComponent is required to have a strong name .

WHAT IS A STRONG NAME?

A strong name provides unique identification for a .NET assembly and identifies it using a simple text name, a version number, culture information, and a public key and digital signature. Its uniqueness is guaranteed by the private/public key pair generated by the Strong Name Utility (sn.exe).


In addition, a serviced component is typically registered (although not required to be) in the Global Assembly Cache (GAC) using the GAC Utility (gacutil.exe). Strongly-named components have a unique identification.

Automatic Transaction Management

For your first ServicedComponent, you can utilize the transaction management capabilities provided by COM+. For instance, the component that follows in Listing 4.40 uses the distributed transaction management services by specifying that the OrderComponent requires a new or existing transaction. Additionally, the method uses AutoComplete, which means the component will automatically commit after the method logic has been successfully completed (without throwing any exceptions) and will roll back if any exception is thrown. The ContextUtil class, which represents the COM+ Object Context class, alternatively provides methods such as SetComplete and SetAbort to manually complete and abort existing transactions.

Listing 4.40 Transaction Management Using Serviced Components
 using System; using System.Reflection; using System.EnterpriseServices;  [assembly: ApplicationName("OrderComponent")]   [assembly: AssemblyKeyFileAttribute("OrderComponent.snk")]  namespace MyApp {  [Transaction(TransactionOption.Required)]  public class OrderComponent : ServicedComponent   {    public OrderComponent()    {    }  [AutoComplete]  public void CreateOrder(String item, int quantity)    {       if (quantity > 10) {          throw new Exception("Quantity to Large");       }    }   } } 

To generate a key pair for a strongly named component, use the Strong Name Utility as shown next:

 
 sn k OrderComponent.snk 

Then compile the component as a shared library and optionally register using the GAC Utility.

 
 csc /target:library OrderComponent.cs gacutil /i OrderComponent.dll 

Now you need to develop a client that uses our serviced component. As shown in Listing 4.41, invoking a serviced component is really the same as invoking any other .NET class.

Listing 4.41 Using a Serviced Component
 using System; using MyApp; public class CreateOrder {    public static void Main()    {       try {       OrderComponent oc = new OrderComponent();       oc.CreateOrder("ABC",5);       Console.WriteLine("Order Created for {1} Items of {0}","ABC",5);       oc.CreateOrder("ABC",15);       Console.WriteLine("Order Created for {1} Items of {0}","ABC",15);       } catch (Exception ex) {       Console.WriteLine(ex.Message);       }    } } csc CreateOrder.cs /r:OrderComponent.dll 

Running the CreateOrder application should yield the following output:

 
 E:\hks\DotNet\Chapter 4>CreateOrder Order Created for 5 Items of ABC Quantity to Large 

After the component is used for the first time, COM+ services automatically creates a COM+ application with the assigned name (shown in Figure 4.2)(ApplicationName) and services the requests for the component in the context of the COM+ runtime.

Figure 4.2. COM+ application for order serviced component.

Object Pooling

Apart from transaction management, COM+ services provides a host of other services to serviced components. Object pooling provides a mechanism where a pool of objects can be precreated and available for servicing clients , thereby removing the overhead typically occurring during creation. After the object is deactivated by a client, it is sent to the object pool, much like a database connection pool, ready to be activated for another client request. Object pooling can be enabled for serviced components by including the ObjectPooling attributes and overriding the CanBePooled method, inherited from ServicedComponent.

 
 using System; ... namespace MyApp {  [[ObjectPooling(Enabled=true, MinPoolSize=5, MaxPoolSize=10)]  public class OrderComponent : ServicedComponent   {         ...  protected override bool CanBePooled()   {   return true;   }  } } 

JIT Activation

In typical rich client applications (Windows applications), clients hold a reference to a serviced component for a prolonged period of time ”for instance, while the user is entering information on the form before submitting a request ”a period known as think time . Just-in-Time activation (JIT) provides a mechanism where a object can be deactivated during the idle time and can be reactivated when the client sends another request. This provides an efficient mechanism to conserve server-side resources. JIT activation is enabled by using the JustInTimeActivation attribute.

 
 using System; ... namespace MyApp {   [JustInTimeActivation]   public class OrderComponent : ServicedComponent   {     ...   } } 

Queued Components

In a number of distributed application design scenarios, a design pattern recommended by architects and application designers is the loosely coupled fire and forget . Fire and forget really is an asynchronous way of dealing with distributed components. Even though (as you will learn in the next section) the .NET Framework does provide a mechanism to interact with the underlying operating system message queuing capability, queued components in COM+ have provided the benefit for object-oriented application developers to use the notion of messaging transparently when asynchronously invoking methods on the components. This functionality is called queued components. .NET Framework provides the capability to create and deploy queued components using a combination of attributes assigned to classes and a definition of a queue interface.

For instance, consider a queued component scenario of your previous order component. A typical order-processing transaction might take an extensive amount of time because it typically interacts with multiple underlying applications. You can utilize the queued component scenario in this example if the front-end application doesn't need an immediate response.

To develop a queued component, create an interface that represents the "business" methods that will be available asynchronously. The rest of the process is similar to that of creating a serviced component, the only difference being that the serviced component inherits both this queue interface as well as the ServicedComponent class, as shown in Listing 4.42.

Listing 4.42 Using Queued Components
 using System; using System.Reflection; using System.EnterpriseServices; [assembly: ApplicationName("QOrderComponent")] [assembly: ApplicationActivation(ActivationOption.Server)] [assembly: ApplicationQueuing(Enabled=true, QueueListenerEnabled=true)] [assembly: AssemblyKeyFileAttribute("QOrderComponent.snk")] namespace MyApp {   public interface IQOrderComponent   {    void CreateOrder(String item, int quantity);   }   [InterfaceQueuing(Interface="IQOrderComponent")]   public class QOrderComponent : ServicedComponent, IQOrderComponent   {    public QOrderComponent()    {    }    public void CreateOrder(String item, int quantity)    {       // replace with actuall process code which creates an order       // into a backend system       // following code simulates a long task       for (int i=0;i<99999;i++)          for (int j=0;j<99999;j++);    }   } } 

As shown in Listing 4.43, using a queued component is also slightly different from calling a regular serviced component. The System.Runtime.InteropServices.Mashal class provides a mechanism to bind to a queue monitor with an appropriate name ( queue:/new:<Component Name>) to be able to use the queued component asynchronously. In the background, COM+ services creates a set of private queues on the message queuing services on the underlying operating system to queue requests to the queued component, which uses a set of configured listeners to facilitate the processing.

Listing 4.43 Using a Queued Component Using Queue Moniker
 using System; using System.Runtime.InteropServices; using MyApp; public class CreateOrder {    public static void Main()    {       try {       IQOrderComponent oc = (IQOrderComponent)            Marshal.BindToMoniker("queue:/new:MyApp.QOrderComponent");       oc.CreateOrder("ABC",5);       Console.WriteLine("Order Request Sent for {1} Items of {0}","ABC",5);       Marshal.ReleaseComObject(oc);       } catch (Exception ex) {       Console.WriteLine(ex.Message);       }    } } 

For instance, running the preceding client application should immediately produce an output "Order Request Sent for 5 Items of ABC", even though as intended, the CreateOrder method has a significant intended execution delay due to the loop.



Microsoft.Net Kick Start
Microsoft .NET Kick Start
ISBN: 0672325748
EAN: 2147483647
Year: 2003
Pages: 195
Authors: Hitesh Seth

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net