The WCF 4.5 beta simplifies configuring WCF, provides better support for code-based configuration, and makes it easier to do code-based configuration in Web sites. Don’t get me wrong: I like the WCF configuration files but, I gather, I may be in a minority. Many developers prefer to configure their WCF services from code where possible. Unfortunately, one of the places where that isn’t possible is the most common place to host WCF services: in a Web application (well, I’m told it was possible but only in the sense that it’s possible to remove your own appendix).
WCF 4.5 (at least, in the beta) provides a simple solution: Add a static/shared method called Configure to your service class and fill it with the code required to configure your service. WCF will call that Configure method at the appropriate moment and pass the method an instance of the ServiceHost class. In your Configure method, you can work with that ServiceHost to configure your service.
What’s especially impressive is how simple it is. The default settings alone mean that if you add an svc file to your Web site then you have a Web Service. You can make that explicit, however, with a single line of code. This example makes the service containing this method available as a Web Service with no WCF-related tags required in the config file at all:
Public Shared Sub Configure(sc AsServiceConfiguration)
You can configure these services by instantiating behavior classes, configuring them, and adding them to the ServiceConfiguration’s Description property’s Behaviors collection. That’s a good thing because, while my previous example was all the code you need (in fact one more line than you needed), it’s probably not all the code you want, for two reasons.
Configuring the Service
First, with just that code you won’t be able to retrieve the WSDL contract for this service (what WCF refers to as service’s “metadata”) so you won’t be able to use Visual Studio’s WCF test client (you also won’t be able to use the Discover button in Visual Studio’s Add Service Reference dialog). For testing purposes, and until you can save to a separate file the WSDL contract that you can give to the developers building the clients/consumers for this service, you’ll want to configure your service to return a WSDL contract. To tell your service to make its metadata available you add code like the following to your Configure method. This code creates a ServiceMetadataBehavior object, sets its HttpGetEnabled property to True (that actually turns on the feature), and add the configured behavior to the Behaviors collection:
Dim behavior As New Description.ServiceMetadataBehavior
behavior.HttpGetEnabled = True
Second, by default, WCF services don’t return a lot of information in their exception messages. That’s a good thing: While that information is very useful in debugging, it probably isn’t something you want to share with the general public. However, in testing, you probably do want that those chattier error messages and you can enable the with this code in the Configure method:
Dim debugBehavior As New Description.ServiceDebugBehavior
debugBehavior.IncludeExceptionDetailInFaults = True
But both of these changes highlight an issue with code-based configuration. In production, you probably don’t want your service freely giving up its contract to whoever asks for it. Instead you probably want to control access to your service’s contracts so that you have some idea who’s using your service and can contact those users when you’re making changes to your service. And you certainly don’t want to send out those verbose error messages from your production system. So, before moving your service to production you’re going to want to change the values used in this code.
The problem is that, with the code I’ve used here, there’s no simple way to inspect the assembly you’re deploying to production to determine if the settings are correct: the code is compiled and is unreadable. One of the nice features of the config files is that you could inspect them (and even change them) with Notepad. The right answer is probably to move settings that will change from one installation to another (e.g. test and production) into your AppSettings where you’ll still have visibility to them.