Chapter 42 covered the architecture and core features of Windows Communication Foundation. With WCF, you can configure a Message Queuing binding that makes use of the Windows Message Queuing architecture. With this, WCF offers an abstraction layer to Message Queuing. Figure 45-14 explains the architecture in a simple picture. The client application invokes a method of a WCF proxy to send a message to the queue. The message is created by the proxy. For the client developer, there’s no need to know that a message is sent to the queue. The client developer just invokes a method of the proxy. The proxy abstracts dealing with the classes from the System. Messaging namespace and sends a message to the queue. The MSMQ listener channel on the service side reads messages from the queue, converts them to method calls, and invokes the method calls with the service.
Next, the Course Ordering application gets converted to make use of Message Queuing from a WCF viewpoint. With this solution, the three projects done earlier are modified, and one more assembly is
added that includes the contract of the WCF service:
- The component library (CourseOrder) includes entity classes for the messages that are sent across the wire. These entity classes are modified to fulfill the data contract for serialization with WCF.
- A new library is added (courseOrderService) that defines the contract offered by the service.
- The WPF sender application (CourseOrdersender) is modified to not send messages but instead invoke methods of a WCF proxy.
- The WPF receiving application (CourseOrderReceiver) is modified to make use of the Wet service that implements the contract.
EntIty Classes wIth a Data Contract
In the library CourseOrder, the classes course, customer, and CourseOrder are modified to apply the data contract with the attributes [DataContract] and [DataMember]. For using these attributes, you have to reference the assembly System. Runtime. serialization and import the namespace System. Runtime Serialization:
The Customer class requires the data contract attributes as well:
With the class CourseOrder, not only the data contract attributes are added, but an override of the ToString() method as well to have a default string representation of these objects:
WCF Service Contract
For offering the service with a WCF service contract, add a WCF service library with the name Course Order Service Contract. The contract is defined by the interface [CoursreOrderService]. This contract needs the attribute [ServiceContract]. If you want to restrict using this interface only with message queues, you can apply the [DeliveryRequirements] attribute and assign the property Queued Delivery Requirements. Possible values of the enumeration Queued Delivery Requirements Mode are Required, Allowed, and Not Allowed. The method AddCourseOrder() is offered by the service. Methods used by Message Queuing can only have input parameters. Because the sender and receiver can run independent f each other, the sender cannot expect an immediate result. With the attribute [OperationContract] the IsOneWay property is set. The caller of this operation does not wait for an answer from the service:
You can. use acknowledgment and response queues to get answers to the client.
WCF Message Receiver Application
The WPF application CourseOrderReceiver is now modified to implement the WCF service and receive the messages. References to the assembly System. ServiceModel and the WCF contract assembly CourseOrderServiceContract are required.
The class CourseOrderService implements the interface ICourseOrderService. With the implementation, the event CourseOrderAdded is fired. The WPF application will register to this event to receive CourseOrder objects.
Because WPF controls are bound to a single thread, the property UseSynchronizationContext is set with the [ServiceBehavior] attribute. This is a feature of the WCF runtime to pass the method call invocation to the thread that is defined by the synchronization context of the WPF application:
Chapter 19, “Threading and Synchronization,” explains the synchronization context.
With the constructor of the class CourseReceiverWindow, a ServiceHost object is instantiated and opened to start the listener. The binding of the listener will be done in the application configuration file.
In the constructor, the event CourseOrderAdded of the CourseOrderService is subscribed. Because the only thing that happens here is adding the received CourseOrder object to a collection, a simple Lambda expression is used.
Lambda expressions are explained in Chapter 7, “Delegates and Events.”
The collection class that is used here is ObservableCollection<T> from the namespace System. Collections. Obj ectMode 1.This collection class implements the interface INotifyCollectionChanged, and thus the WPF controls bound to the collection are informed about dynamic changes to the list:
The WPF elements in the XML code now make use of data binding. The ListBox is bound to the data context, and the single-item controls are bound to properties of the current item of the data context:
The application configuration file defines the net Msmq Binding. For reliable messaging, transactional queues are required. To receive and send messages to non-transactional queues, the exactly Once
property must be set to false.
net Msmq Binding is the binding to be used if both the receiver and the sender application are WCF applications. If one of these applications is using the Sys tern.Messaging API to send or receive
messages, or is an older COM application, you can use the msmq lntegration Binding.
The Click event handler of the buttonProcessOrder button removes the selected course order from the collection class:
WCF Message Sender Application
The sending application is modified to make use of a WCF proxy class. For the contract of the service, the assembly CourseOrderServiceContract is referenced,and the assembly System. ServiceModel is required for use of the WCF classes.
In the Click event handler of the buttonSubmit control,the Channel Factory class returns a proxy. The proxy sends a message to the queue by invoking the method AddCourseOrder():
The application configuration file defines the client part of the WCF connection. Again, the net Msmq Binding is used:
When you start the application now, it works in a similar way as before. There is no longer need to use classes of the System. Messaging namespace to send and receive messages. Instead, you write the application in a similar way as using TCP or HTTP channels with WCF.
However, to create message queues and to purge messages, you still need the Message Queue class.WCF is only an abstraction to send and receive messages.
If you need to have a System. Messaging application to communicate with a WCF application, you can do this by’using the msmq IntegrationBinding instead of tire net Msmq Binding. This binding uses the message format that is used with COM and System.Messaging.
Message Queue Installation
Message queues can be created with the MessageQueue. Create() method. However, the user running an application usually doesn’t have the administrative privileges that are required to create message queues.
Usually, message queues are created with an installation program. For installation programs, the class MessageQueueInstaller can be used. If an installer class is part of an application, the command-line
utilty installutilty.exe (or a Windows Installation Package) invokes the Install() method of the installer.
VIsual Studio has a special support for using the MessageQueueInstaller with Windows Forms applications. If a MessageQueue component is dropped from the toolbox onto the form, the-smart tag of the component allows you to add an installer with the menu entry Add Installer. The . MessageQueueInstaller object can be configured with the properties editor to define transactional queues, journal queues, the type of the formatter, the base priority, and so on.
Installers are discussed in Chapter 16, “Deployment.”