Visual C#. NET 2003 Unleashed

Advanced COM+

This section will show you some of the more powerful features of COM+ and how to write code that utilizes those technologies, such as loosely coupled events and queued components.

Events

In the .NET Framework, you can write code that subscribes to events published by other classes. The classes that publish events can reside in other assemblies or within the same assembly. One thing those classes can't do is publish events when the client applications aren't running.

With the COM+ loosely coupled event system, an event publisher (also a serviced component) can publish an event without knowing the list of subscribers. COM+ will handle transmitting the event to all subscribers, including activating dormant components that have registered as listeners for that event.

There are three requirements for creating a loosely coupled event system: The publisher and subscriber must both inherit from ServicedComponent, they must both implement the same interface, and there must be a subscription configured between the receiving (listening) component and the publishing component. The code in Listing 40.4 shows the event class, the event subscriber (often called the sink) class, and the shared interface between the two.

Listing 40.4. The Event Class, Subscriber Class, and Shared Interface

using System; using System.EnterpriseServices; using System.Windows.Forms; namespace ServicedApplication { /// <summary> /// Summary description for LooselyCoupledEvent. /// </summary> [EventClass()] public class LooselyCoupledEvent : ServicedComponent, ILooselyCoupledEvent { public void EventMethod(string evtMessage) { } } public interface ILooselyCoupledEvent { void EventMethod( string evtMessage ); } public class LooselyCoupledEventSubscriber : ServicedComponent, ILooselyCoupledEvent { public void EventMethod(string evtMessage) { MessageBox.Show(evtMessage, "Event Subscriber"); } } } }

One thing that might not be obvious at first is that you don't need to create an instance of the subscriber component for it to receive the event from the publisher. The following code in another serviced component actually publishes the event:

public void PublishEvent( string message ) { LooselyCoupledEvent lce = new LooselyCoupledEvent(); lce.EventMethod( message ); }

All you need to do now is set up the subscription between the publisher and the subscriber and invoke the PublishEvent method from a client application and you will be able to see COM+ events in action.

To rig up the subscription, find the subscriber component, expand the node, and right-click the Subscriptions folder. When you add a new subscription, a wizard will appear, as shown in Figure 40.3.

Figure 40.3. The COM+ New Subscription Wizard.

When you add the following code to a client application, it will trigger an event publish, and you should see a message box appear:

ServicedApplication.SampleClass sc = new ServicedApplication.SampleClass(); sc.PublishEvent("Hello to all client events!");

When this code is executed after a subscription has been defined, the message shown in Figure 40.4 will appear.

Figure 40.4. The message that appears as a result of a COM+ event notification.

Queued Components

As mentioned earlier in the chapter, you can hook a COM+ component up to a message queue to provide deferred, asynchronous method execution. Instead of instantiating a component directly, you instantiate the component with a reference to its queue and the queued component will operate asynchronously with your method calls being serialized into messages in the queue.

With a few exceptions, every aspect of COM+ programming remains the same between queued components and regular (synchronous) components. The first exception is that methods of queued components cannot return values. The second is that clients need to use a specific syntax to bind to the queued component instead of creating an instance using the new keyword.

To instruct COM+ that queuing should be enabled, use the ApplicationQueuing attribute with the Enabled parameter set to true and the QueueListenerEnabled parameter set to true. This will set up a queue to service the component and immediately start listening on that queue. Use the InterfaceQueuing attribute to indicate the name of the interface that the particular class is implementing, allowing for proper message queue operation.

Finally, when you have created a queued component, you will need to create an instance of that component. Instead of using the new keyword, you need to use the Marshal.BindToMoniker method. For example, if you created a queued component that implements the interface IAsyncComponent, you might use the following code to create an instance of that component:

IAsyncComponent iac; Iac = (IAsyncComponent) Marshal.BindToMoniker("queue:/new:MySampleClass. AsyncComponent");

This will not only create an instance of a queued component, but will also obtain the resources necessary for writing serialized method calls to the associated queue.

    Категории