The How
The following excerpt shows how to expose a WCF Data Service via the Azure AppFabric Service Bus, using a self-hosted ServiceHost.
using(var host = new DataServiceHost(
typeof(PersonsDataService), new Uri[0])){
host.AddServiceEndpoint(
typeof (IRequestHandler),
new WebHttpRelayBinding(
EndToEndWebHttpSecurityMode.Transport,
RelayClientAuthenticationType.None),
“https://my-namespace.servicebus.windows.net/pds”)
.WithServiceBusTransportCredentials();
host.Open();
Console.WriteLine("host is opened, press any key to exit");
Console.ReadKey();
}
where
- PersonsDataService is the data service to be exposed;
class PersonsDataService : DataService<MyDataModel>{
…
public static void InitializeService(
IDataServiceConfiguration config) {
…
}
…
}
- IRequestHandler is the WCF Data Services generic service contract (see below);
- WebHttpRelayBinding is the Azure AppFabric Service Bus binding for the “web programming model”.
- and WithServiceBusTransportCredentials is an extension method for configuring the service bus transport credentials
public static ServiceEndpoint WithServiceBusTransportCredentials(this ServiceEndpoint edp) {
ConfigureTransportCredentials(edp);
return edp;
}
public static void
ConfigureTransportCredentials(ServiceEndpoint edp) {
var tcred = new TransportClientEndpointBehavior();
tcred.CredentialType =
TransportClientCredentialType.SharedSecret;
tcred.Credentials.SharedSecret.IssuerName = IssuerName;
tcred.Credentials.SharedSecret.IssuerSecret = SharedSecret;
edp.Behaviors.Add(tcred);
}
The Why
WCF Architecture
The Windows Communication Architecture is based on two layers:
- The Channel Model Layer is a stack of channels that operate on messages, composed by
- Zero or more protocol channels, implementing protocols such as WS-Security.
- One transport channel that send or receives the messages from the transport medium (e.g. TCP, pipes). This transport channel uses a message encoder/decoder to translate between the messages handled by the protocol channels and the transport’s byte streams.
- The Service Model Layer is responsible for the translation between messages and service method calls.
WCF Data Services
WCF Data Services are layered on top of the WCF Service Model:
- The System.Data.Services.IRequestHandler interface is a generic Web HTTP programming model service contract configured to accept any URL (UriTemplate=”*”) and any HTTP method (Method=”*”).
[ServiceContract]
public interface IRequestHandler {
[OperationContract,
WebInvoke(UriTemplate = "*", Method = "*")]
Message ProcessRequestForMessage(Stream messageBody);
}
- The base class DataService<T>, from which the concrete data service class derives, implements the IRequestHandler interface.
[AspNetCompatibilityRequirements(
RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed),
ServiceBehavior(
InstanceContextMode = InstanceContextMode.PerCall)
]
public class DataService<T> : IRequestHandler, IDataService {
...
public Message ProcessRequestForMessage(Stream messageBody){...}
...
}
Azure AppFabric Service Bus
The Azure AppFabric SDK contains several bindings to expose and consume services via the service bus, namely the WebHttpRelayBinding that uses the Web HTTP programming model. This binding defines a channel stack with a RelayHttpTransportChannelListener that opens a TCP connection to the services bus and listens to messages relayed by it.
Since the Service Bus bindings extend the channel layer and the WCF Data Services are layered on top of the Service Model Layer, their composition is straightforward.