One of the really nice things about WCF in general, is that we can offload a ton of hard coded remoting details to a host *.config file. On the same token, one of the worse things about WCF is building the hosting side *.config file....at least if you are not using WCF 4.0. As you might have noticed while working with WCF, many services need the same basic settings: same binding (HTTP, TCP, etc), support for MEX, etc.
Establish these basic details time and time again can be annoying to say the least. However, under .NET 4.0, WCF has some built in default binding endpoints, including a default usage of MEX. If you were to open the machine.config file for a .NET 4.0 installation, you will find a new section which specifies default WCF binding classes to use, if you specify an simple base address:
<system.serviceModel>
...
<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>
...
</system.serviceModel>
Given this, you could now expose an HTTP and TCP endpoint using nothing more than the following host configuration file:
<configuration>
<system.serviceModel>
<services>
<service name="MagicEightBallServiceLib.MagicEightBallService" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MagicEightBallService"/>
<add baseAddress="net.tcp://localhost:8099/MagicEightBallService"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
That's it! If you need to change any of the default properties of these default bindings, simply define an unnamed WCF binding in your <bindings> section. For example:
<configuration>
<system.serviceModel>
<services>
<service name="MagicEightBallServiceLib.MagicEightBallService" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MagicEightBallService"/>
<add baseAddress="net.tcp://localhost:8099/MagicEightBallService"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding openTimeout = "00:30:00" />
</basicHttpBinding>
<netTcpBinding>
<binding closeTimeout="00:15:00"/>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
Finally, if you need to enable MEX, you no longer need to manually build an endpoint for IMetadataExchange and establish a complex custom behavior. The following is all you need:
<configuration>
<system.serviceModel>
<services>
<service name="MagicEightBallServiceLib.MagicEightBallService" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MagicEightBallService"/>
<add baseAddress="net.tcp://localhost:8099/MagicEightBallService"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding openTimeout = "00:30:00" />
</basicHttpBinding>
<netTcpBinding>
<binding closeTimeout="00:15:00"/>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To get default MEX, don't name your <serviceMetadata> element-->
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
As I am sure you would agree, these are awesome simplifications. While WCF has always been a simple programming model, the details of host configuration was quite painful. Looks like things are much, much better with 4.0
Happy coding!
eda40855-9ad0-433e-9bf6-c9a08047eb0f|2|5.0