The WCF Routing Service is a standalone service that benefits from being hosted in AppFabric and routing to Workflow Services. It can be used to enable scenarios such as workflow service versioning, content-based routing, and routing to back up workflow services in the face of an outage.
What’s Changed?
In "Routing Messages in WCF 4," Michele Leroux Bustamante provided an introduction to the RoutingService in .NET 4 Beta 1. In this article, I apply the WCF RoutingService to Workflow Services built under .NET 4 Beta 2, and examine how to set it up and troubleshoot its configuration with AppFabric Beta 1.
Since that article was published, the major change to the WCF RoutingService was primarily that it moved from being an AppFabric (codenamed "Dublin") feature into the core of the .NET framework. Specifically, the WCF Routing Service was moved from the Microsoft.ProcessServer.Messaging assembly to the System.ServiceModel.Routing assembly. The namespace has been similarly updated to reflect that the RoutingService is now considered a part of WCF 4. Beyond that, the RoutingService has undergone a label update, with is now being consistently referred to as the router or routing service in place of the forwarding service. This last change manifests itself in the key behavior used to enable the routing service, whose element now reads “routing” instead of “forwardingBehavior.”
Setting up in AppFabric
While the RoutingService can be self hosted in a standalone process, it need to be hosted by AppFabric to take advantage of AppFabric monitoring features. The RoutingService is a WCF service, and in .NET 4 there are two approaches that one can take to host within AppFabric. Both approaches assume you have created a web application in AppFabric.
The SVC Approach
The first approach is to create an SVC endpoint by adding an SVC file to an application with the ServiceHost directive indicating the RoutingService type in the Service attribute. The ability to create SVC endpoints for WCF services was the approach one needed to take in .NET 3.x in order to host services with IIS/WAS (of which AppFabric is an evolution). Figure 1 shows the directive you would always use in an SVC file that represents a RoutingService endpoint.
Figure 1: ServiceHost directive in an SVC file
Configuration of the SVC hosted service goes in web.config. The association between the Service described in the SVC’s ServiceHost directive and its configuration in the web.config’s Service element is made by the name attribute on the Service element (which should be System.ServiceModel.Routing.RoutingService), as Figure 2 shows.
Figure 2: Service element in web.config that applies to RoutingService hosted in SVC file
There is additional configuration specific to the RoutingService, which we will explore after introducing the other approach to hosting the RoutingService in AppFabric.
The SVC-less Approach
The second approach is to create the service entirely via the web.config. New to .NET 4 are SVC-less service activation endpoints, which allow you to define the relative address for the endpoint. If the address you specify names an SVC file, it will appear (from the caller's perspective) for all intents and purposes as if AppFabric contains an SVC file in the applications’ file system, even though no such file would actually exist. For example, you might enable a metadata exchange endpoint on the routing service and if you were to navigate to the URL of your svc file, such as http://localhost/myService/Router.svc, you would get the expected service helper page in your browser.
The equivalent of the ServiceHost directive in the SVC file is described in web.config via the serviceActivations child element of the serviceHostingEnvironment, as Figure 3 shows. Each “virtual” service endpoint is described via an add element within the serviceActivations element. The relativeAddress attribute of the add element defines the URI of the endpoint clients will access, and when hosted within AppFabric it's always relative to the path of the containing Web application. The service attribute names the type of the service to activate (in this case the RoutingService type is provided with its assembly qualified name).
The serviceHostingEnvironment element itself must be placed as a child of the system.serviceModel element in web.config. We need some way to tie the service that is activated to its configuration. This is accomplished exactly as was done for the SVC approach in Figure 3—the service element must have a name of System.ServiceModel.Routing.RoutingService. With that association in place, we can then define the necessary behavior and endpoint configuration that enables routing.
As we will explore shortly, the RoutingService is generally enabled entirely via the web.config. In the typical deployment there are no additional assemblies or files that need to be deployed with it. This approach provides the value of having only one file to maintain to both describe the activation endpoint and configure the service—all the settings of your RoutingService router will be centrally located in web.config.
In both cases, the Application Pool used by the web application must be configured to use.NET Framework 4. You can do this within IIS Manager by selecting your web application in the Connections tree view and selecting the Basic Settings… link in the Actions pane. Next, click the Select… button on the Edit Application window. In the Select Application Pool, ensure that the pool selected in the drop down lists .Net Framework Version 4.0 in its properties (see Figure 4). If it does not, you will need to change the selected pool to one that does.