For a demo I am working on, I’m creating an OData feed. This OData feed is in essence a WCF service which is activated using System.ServiceModel.Activation.ServiceRoute. The idea of using that technique is simple: map an incoming URL route, e.g. “http://example.com/MyService” to a WCF service. But there’s a catch in ServiceRoute: unlike ASP.NET routing, it does not support the usage of route data. This means that if I want to create a service which can exist multiple times but in different contexts, like, for example, a “private” instance of that service for a customer, the ServiceRoute will not be enough. No support for having http://example.com/MyService/Contoso/ and http://example.com/MyService/AdventureWorks to map to the same “MyService”. Unless you create multiple ServiceRoutes which require recompilation. Or… unless you sprinkle some route magic on top!
Implementing an MVC-style route for WCF
Let’s call this thing DynamicServiceRoute. The goal of it will be to achieve a working ServiceRoute which supports route data and which allows you to create service routes of the format “MyService/{customername}”, like you would do in ASP.NET MVC.
First of all, let’s inherit from RouteBase and IRouteHandler. No, not from ServiceRoute! The latter is so closed that it’s basically a no-go if you want to extend it. Instead, we’ll wrap it! Here’s the base code for our DynamicServiceRoute:
public class DynamicServiceRoute : RouteBase, IRouteHandler
{
private string virtualPath = null;private ServiceRoute innerServiceRoute = null;private Route innerRoute = null;public static RouteData GetCurrentRouteData(){}public DynamicServiceRoute(string pathPrefix, object defaults, ServiceHostFactoryBase serviceHostFactory, Type serviceType){}public override RouteData GetRouteData(HttpContextBase httpContext){}public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values){}public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext){}
}
As you can see, we’re creating a new RouteBase implementation and wrap 2 routes: an inner ServiceRoute and and inner Route. The first one will hold all our WCF details and will, in one of the next code snippets, be used to dispatch and activate the WCF service (or an OData feed or …). The latter will be used for URL matching: no way I’m going to rewrite the URL matching logic if it’s already there for you in Route.
Read more: Maarten Balliauw {blog}