One of the most annoying parts of developing with WCF and Silverlight is the configuration files. I have always hated WCF configuration files. While powerful and necessary, they are just the opposite of fun.
Using Visual Studio 10 “publish” web functionality, the Web.Config files could be transformed with Web.Release.Config. Not bad. Makes things a little easier. Here’s the rub: when creating a WCF/Silverlight application, the publish transformation would transform the web.config for the server, but NOT the ServiceReferences.ClientConfig on the client. What a PITA.
Some Microsoft blogs show that the preferred solution for this problem is to rename the published .xap file to .zip, then open the .zip file, extract the .ClientConfig file, change it, save it, re-zip it, then rename the .zip back to .xap.
Really?
After the first time, this got so cumbersome I wanted to shoot myself. Really I wanted to shoot someone at Microsoft. :) Anyway, Google provided a few solutions, none totally to my liking.
My boss pushed the ConfigSwitcher project on me, as in theory it seems to be what I am looking for. Being pre-VS2010, this didn’t use the XML transformation functionality but instead used a full copy of the config file, and required another .exe that had to be copied to each machine that this would be run on. But it is a good idea.
So my strategy is to write custom build tasks that copy the ServiceReferences.ClientConfig file to a temp file before the build, then run the XML transformation using ServiceReferences.$(Configuration).ClientConfig and output to ServiceReferences.ClientConfig. Then after the build completes, and the transformed file has been put into the .xap file, delete the ServiceReferences.ClientConfig, and copy the original file (which is now a temp file) back.
So…
Before Build:
- Copy ServiceReferences.ClientConfig to ServiceReferences.Build.ClientConfig
- Transform ServiceReferences.Build.ClientConfig to ServiceReferences.ClientConfig using ServiceReferences.$(Configuration).ClientConfig
and After Build:
- Delete ServiceReferenes.ClientConfig
- Move ServiceReferenes.Build.ClientConfig to ServiceReferences.ClientConfig
And, I don’t want any more baggage required. I don’t want a program that has to be installed on developer machines, and I don’t want a macro that has to be present on developer machines. I don’t even want custom MSBuild targets installed. So, to do this, I use the BeforeBuild and AfterBuild target overrides of the .csproj file, and I use the already present XmlTransform task of Visual Studio 10.
So, unload the project and edit the .csproj file directly. Scroll to the bottom and there are commented out BeforeBuild and AfterBuild overrides. Adding this snippet:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="BeforeBuild" Condition="Exists('ServiceReferences.$(Configuration).ClientConfig')">
<Move SourceFiles="ServiceReferences.ClientConfig" DestinationFiles="ServiceReferences.Build.ClientConfig" />
<TransformXml Source="ServiceReferences.Build.ClientConfig" Destination="ServiceReferences.ClientConfig" Transform="ServiceReferences.$(Configuration).ClientConfig" />
</Target>
<Target Name="AfterBuild" Condition="Exists('ServiceReferences.Build.ClientConfig')">
<Delete Files="ServiceReferences.ClientConfig" />
<Move SourceFiles="ServiceReferences.Build.ClientConfig"
DestinationFiles="ServiceReferences.ClientConfig" />
</Target>
gives me what I want. If there is a file named ServiceReferences.Release.ClientConfig and I am building a Release version, then the transformation is run at compile time, and the transformed .ClientConfig is put into the .xap file.
870c1f14-0dee-445a-9194-2c2612c99863|2|5.0
Development
silverlight | visual studio