When first learning Silverlight, having often utilized the “Add Web Reference” functionality in Visual Studio in days gone by, I reached for the alluring “Add Service Reference” functionality when adding references to WCF services to my Silverlight projects. I encountered a few problems using this approach and began to search for a better way to reference WCF services.
Project Bloat
The first problem I noticed was the sheer number of files generated by Visual Studio when you add a service reference. If you’re using source control (and you should be), any modification made to a service reference is going to delete several files and replace them with new ones. When checking these changes into source control, it can sometimes be confusing trying to figure out how to get your source checked in in a valid state.
Reusing Referenced Assemblies
Second problem I found I was having was that I was often getting errors and warnings when adding or modifying a service reference. These came in different flavors, but most all complained about the format of the WSDL being received from the service. With some trial and error, I figured out that the problems were being caused by the default behavior of Visual Studio when adding a reference in respect to reusing types in referenced assemblies. When adding a service reference, the below dialog appears.
If you click on the Advanced button, this dialog appears.
By default, the “Reuse types in referenced assemblies” checkbox is checked and the “Reuse types in all referenced assemblies” radio button is selected. If you’re having problems getting client proxies to generate for your services, try clearing the checkbox as this seemed to be the solution for me.
Location, Location, Location
The third problem I’ve had with adding references this way is probably the most important. With the Add Web Reference I knew and loved, it was a fairly simple matter to modify the generated Reference.cs file to pull the URL for the web service endpoint from a configuration file. But, when adding a service reference with visual studio, whatever endpoint you specify when adding the reference gets scattered through various of the generated files which makes manual modification extremely difficult.
When I’m working with a Silverlight project, I typically like to have all the services running locally while I’m developing to facilitate debugging and modification of the services which means that my service references need to be pointing to localhost. Before I deploy, I have to go to each reference and reconfigure it to point to the production server which means that any modified version of my services have to already exist on the server and all this makes deployment a huge headache. If my shop employed a full set of environments - dev, QA, staging, prod – I’m sure I’d go postal.
The Search for a Better Way
In thinking about the problem, I realized that what I needed was a simple way to generate a client proxy. I could then build my address, binding and channel in code, pulling any of the necessary pieces of configuration from a config file. My first thought was to create the proxy class using SvcUtil.exe. I soon found, though, that the proxies generated by this tool are incompatible with Silverlight. I then found out about a tool called SlSvcUtil.exe that generates proxies specifically for Silverlight. Unfortunately, this tool is supposed to ship with Silverlight 3 and I’m still working in version 2.
For now, I’ve found two alternatives. First is a bit of a hack, but still a fairly easy way to generate proxies that I found here. Basically, this blog post suggests using the “Add Service Reference” functionality in Visual Studio to generate a reference.cs, saving that class and then deleting the service reference. I also found an article by David Betz, here, that takes you through an excellent explanation of the details of the inner workings of WCF with Silverlight and suggests writing proxies by hand.
It’s good to have choices and I’m sure I can find circumstances where each approach will be beneficial.