[Note: all the information was gathered based on a close-to-Beta 1 build of .NET Framework 4.0 and Visual Studio 2010. Details may vary and change]
Windows Communication Foundation version 4 (WCF4) is not such a big step when compared to Windows Workflow Foundation version 4 (WF4) - or what would you actually call a complete re-write? ;).
But there are some very nice feature additions to the stack - and unfortunately a lot of features we and friends did suggest to Microsoft that did not (yet?) make it into WCF4 (so at least not in Beta 1).
One of these new features is simplified configuration:
- No more need for <service> tag to configure a service.
- Configuration of default bindings and behaviors.
ServiceHost serviceHost = new ServiceHost(typeof(HelloService),
new Uri("http://localhost:7777/Services/Hello"),
new Uri("net.tcp://localhost:7778/Services/Hello"));
serviceHost.Open();
Console.WriteLine("WCF Service is running.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
serviceHost.Close();
Pretty common stuff. Now let's look at the corresponding service config section in app.config:
<configuration>
</configuration>
Ooops, where is the meat? Gone. Nothing necessary here. This is a new feature of WCF4 (and of course also works if you are not a config guy but rather hook up everything in code).
The ServiceHost still opens successfully and we can see a fully set up ServiceHost instance in the debugger, containing service endpoints, using defaults bindings, aha! Let's take a look at the debugger:
For the "net.tcp" scheme it uses a netTcpBinding-based endpoint, for "http" it uses basicHttpBinding, etc (see below for the full default list).
There is a default endpoint per implemented contract (as you may guess from the screenshot) by the service. I.e., if our service implements IHello and IHelloEx we will have two endpoints for each base address - in the case of this sample we would have four endpoints.
But we can go a step further. What if we need to tweak the default binding's settings? Just tweak the default binding to be used by default endpoints (note that the default binding configuration doesn't show a name property).
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="9999999">
<readerQuotas maxArrayLength="9999999"/>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
OK - but I must confess that in a large number of cases I do not need interop via HTTP and the basicHttpBinding and thus try to use a custom binding that gives me binary encoding over HTTP and also shows improved performance in a lot of scenarios. How can I use my custom binding as a default binding for a given protocol scheme?
Welcome protocol mappings. With a protocol mapping entry you can specify which binding is the new default binding for a certain protocol scheme. This is the default protocol mapping line-up:
<protocolMapping>
<add scheme="http" binding="basicHttpBinding"/>
<add scheme="net.tcp" binding="netTcpBinding"/>
<add scheme="net.pipe" binding="netNamedPipeBinding"/>
<add scheme="net.msmq" binding="netMsmqBinding"/>
</protocolMapping>
If we now want to customize the mapping for http to use a custom binding, then we can do it like this:
<protocolMapping>
<clear scheme="http" />
<add scheme="http" binding="customBinding" bindingConfiguration="binaryHttp" />
</protocolMapping>
<bindings>
<customBinding>
<binding name="binaryHttp">
<binaryMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
OK, and what about service behaviors? This is also possible by defining a standard service behavior. The service behavior with name="" will be picked up by our service (similar to the default binding feature).
Ah, no more forgetting to attach the defined service behavior to the service config via the behaviorConfiguration attribute :)
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding>
<readerQuotas maxArrayLength="9999999"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
That's it for now for a first introduction to configuration enhancements in WCF4.
Stay tuned for more.
Comments