Latest Tweet:
  • Loading...

On the Silverlight.net forums there are several questions about how to configure Silverlight applications. A common question is how to change the URL of a WCF service you are consuming. Another common question is how pass in some user defined configuration settings. There are several interesting solutions, and a couple of days ago Bill Reiss posted an article about “Calling WCF on the server of origin from Silverlight”. Bills solution involves using the HTML Bridge to grab the current URI, and building up the URL of the web service, and then creating the service client using one of the constructors allowing you to manually specify binding and endpoint. This is all cool and really helpful in many cases, but the ServiceReferences.ClientConfig file is there for a reason. I think a lot of developers are a bit confused about how to use this file. And I don’t blame them. In Silverlight 2 Beta 1 this file was generated by Visual Studio, but was not read by the WCF runtime. In Beta 2 this was fixed, and the WCF runtime will now read and use the configuration file.

A lot of developers are afraid they have to rebuild their application to change web service configurations; something Bill also write in his blog post:

This is fine if you're hitting a service like Digg or one of the other public web service APIs out there, but not if you want to be able to test on your own machine and also deploy the same XAP to your server without rebuilding.

You could go ahead and change this to the URI on your server and rebuild, but then it won't work locally for testing unless you have a crossdomain file on your server, and you would be hitting your server's web service, not your local one while testing.

When building a Silverlight 2 application Visual Studio 2008 will spit out a XAP file in the Client Bin directory. The XAP file is just a standard ZIP archive containing some assemblies, the configuration file, a manifest file, and any resources you might have added to your project and market as content. It’s completely safe to rename it to ZIP, unpack it, make changes to the ServiceReference.ClientConfig file and package it all back together to a XAP file. Turns out repacking your XAP file is actually a good idea. Back in May Valeri Hristov discovered that he could chop 1MB of a 3MB large Telerik example application by repackaging it using the 7Zip application. Later David Anson followed up with some more examples showing a 22% average saving by repacking the XAP file… Why Microsoft is using such an inefficient ZIP implementation I don’t know –hopefully this will be fixed before release. Until then creating a post-build event that repackages your XAP will probably be the easiest 22% savings you will get all day.

Content of a XAP file

Anyway, let’s get back to configuration. Now that we can reconfigure our Silverlight application without rebuilding it we might be able to use the configuration file for more useful stuff. Silverlight does not come with a full configuration API like the full .NET framework. You do have the System.Configuration namespace, but it only contains some internal, abstract classes used by the Silverlight WCF stack. If you search for “configuration” in Reflector targeting Silverlight 2.0 you get some hits in the System.ServiceModel.Configuration namespace as well. It got configuration section handlers used by WCF to read information about your web service bindings and end points. All classes are internal and not really helpful for handling general application configuration.

Since the ServiceReference.ClientConfig is a plain XML file there is nothing stopping us from adding our own elements to the file. I decided to use the application setting convention we’re used to from .NET, and added an appSettings element with a bunch of key-value pairs elements. The application continued to run just fine with these additional elements. I also tried adding and removing service references from Visual Studio to see if it would screw up my changes. Thankfully Visual Studio only touched the serviceModel element, and didn’t care about our appSettings element. The ServiceReference.ClientConfig file now looks something like this:

configsample1

This is quite handy, as we can keep all application settings in one file using a format developers know. Next step is writing some code to read the configuration file. I decided to mimic how things work in the full .NET framework by creating a ConfigurationManager class with an AppSettings property. To parse the configuration file I used LINQ to XML which made it really easy to extract the key-value pairs.

configsample2

In the full framework the AppSettings property is of type NameValueCollection. This collection does not exist in Silverlight, so instead of re-implemented it I created a simple class backed by dictionary, exposed as an index property.

configsample3 

You read the application settings the same way you are used to from any .NET application:

configsample4

Hopefully this post gives you a better understanding how Silverlight 2 applications are packaged, and how to configure your application without rebuilding it. If I was consuming WCF services in my project I would add configuration management to my automated build process. It would be fairly simple to write a build script that repackages the XAP with a more efficient ZIP implementation, as well as building different versions for test, staging and deployment.

<February 2010>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213