Receiving Output from a Queued Component

Banishing all output options for a queued component would be too draconian and impractical. Sometimes expecting output from a queued component is appropriate. Consider the online shoe store. After the Shipment object ships the order, you would like it to notify another object about it. The Store object would like to pass in the Notification object as a parameter to the ShipOrder( ) method.

From a design perspective, it is a good idea to decouple the notification actions from the Shipment process itself. You should decouple the action to ensure that the Shipment object knows only about a generic notification interface and that it calls a method on it once the order is shipped. It is up to the Store object to decide which notification object to pass in as a parameter. You could have multiple implementations of the Notification interface—for example, one Notification object sends an email to the customer to say that the shoes are on the way and another also sends promotional material.

You have already seen that COM+ allows you to pass in interface pointers for objects that support the IPersistStream interface. COM+ also lets you pass in as a method parameter an interface pointer to another queued component. This technique is called Response Object because it allows the client to receive a response from the queued component and be notified about the results of the queued call. The response object does not need to support the IPersistStream interface, as COM+ will not try to transfer it by value to the queued component.

The client can use a response object in two ways. First, it can create the response object, create the queued component, and pass in the response object interface pointer (which actually points to the response object recorder). After the method call, the client can release the response object.

Figure 8-6 shows how a response object in the online store example is used to send notification email to the customer once the order is processed and shipped.

In the example, the customer submits the purchase order to the Store objects (Step 1). The Store object creates a Notification object (Step 2) and a Shipment object (Step 3), in both cases creating recorders only. The Store object passes in the Notification object as a parameter for the Shipment object. The Shipment recorder knows how to extract from the Notification recorder its queue name and location, and packs it in the message (Step 4). When the method call is played back to the Shipment object (Step 5), based on the information in the message, the player creates a notification recorder (Step 6) and passes it as a method parameter to the Shipment object. The Shipment object calls methods on the Notification recorder (Step 7). Once released, the notification recorder posts the queued calls to the Notification queue (Step 8), where they are eventually played back to the Notification object (Step 9). In this example, the Notification object then notifies the customer about the shipment by sending him email (Step 10).

Online store example: using a response object to send notification email

Figure 8-6.  Online store example: using a response object to send notification email

The second way a client can use a response object is to pass in string method parameters that instruct the queued component how the response object should be created. In the example, the Store object would create only the Shipment recorder and pass in as parameters where and how the Shipment object should create the Response object (machine and queue name, authentication level, and so on). The Shipment object would use these parameters as arguments for the moniker to create the Notification object.

Passing in a queued component as a parameter is more transparent to both the client and the queued component and does not contaminate the interface with parameters, which expose execution location and invocation mode. However, passing in the response object queue information provides ultimate flexibility for the client controlling the response object.

Error handling is another use for response objects. The client has no way of knowing about the success of the queued call. Imagine, for example, that while processing the order, the Shipment object was unable to complete it successfully; perhaps the vendor ran out of shoes in the requested color, or the customer supplied an expired credit card number.

The Shipment object cannot possibly handle all the error cases correctly. However, it can notify the response object that the order processing failed. The response object notifies the customer—perhaps requesting the customer to select a different color or supply a new card number. Error handling is the subject of the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset