Tuesday, June 14, 2011

Build Silverlight ServiceReferences.ClientConfig for Staging AND Prod environment

You want to automate Silverlight Build and Deployment with Team Build of the TFS 2010 ?

Well you will soon be faced to the problem related to the ServiceReferences.ClientConfig file.
Indeed, this file, which references the WCF services inside your *.xap, has to be different for every environment.

So how to automate something ??

Here are possible ways :
  • Don't use those files, but rather store the information in a file such as WebConfig. It is a net solution especially if you are a Software vendor with many different customer (you dont want to unzip and edit your file per customer, just deliver exactly the same *.xap). However, this solution is quite 'tecky' to modify your Silverlight code to work that way,
  • You could create a tool based on a library to unzip then edit your XAP, http://sharpdevelop.net/OpenSource/SharpZipLib/Default.aspx
  • You could manually use 7-Zip to edit the Xap (just associate *.xap to 7-Zip) and change "Localhost" to your new endpoint,
  • You could use for instance InstallShield / WIX installer to perform this task,
  • An elegant and automated way is to use the *.csproj and Team Build to do that.
                . ServiceReferences.Staging.ClientConfig
                . ServiceReferences.Prod.ClientConfig
    This is the solution detailed here after.
In a *.csproj you could have noticed the following commented lines :
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  <Target Name="AfterBuild">

Using the include's functionnality of Microsoft.Common.targets (more info here or here) is the method used, except that we are going to do it for a TeamBuild 2010.

    <Content Include="ServiceReferences.ClientConfig">
    <Content Include="ServiceReferences.Staging.ClientConfig">

Which gives the following in VS2010 :

Then, in the csproj, perform a conditional execution of a XCOPY. For instance use either Condition="'$(IsDesktopBuild)'=='true'" but it is no more supported. Or, prefer using  $(BuildingInsideVisualStudio)

  <!-- Detect if Build inside Visual Studio (i.e.) or Team Build TFS 2010 -->
    <Exec Condition="$(BuildingInsideVisualStudio)=='true'"
        Command="XCOPY ServiceReferences.Dev.ClientConfig ServiceReferences.ClientConfig /R /Y"
IgnoreExitCode="true" />
    <Exec Condition="$(BuildingInsideVisualStudio)!='true'"
        Command="XCOPY ServiceReferences.Staging.ClientConfig ServiceReferences.ClientConfig /R /Y"
IgnoreExitCode="true" />
    <Exec Condition="$(BuildingInsideVisualStudio)!='true'" 
        Command="DIR *.* > BuildingInsideVisualStudio_NotTrue.txt"
IgnoreExitCode="true" />
    <Exec Condition="$(BuildingInsideVisualStudio)=='true'"
        Command="DIR *.* > BuildingInsideVisualStudio_True.txt"
IgnoreExitCode="true" />

Done !

Next step is to use the file ServiceReferences.Staging.ClientConfig the same way as a Web.Config file, that uses XSLT transform to decrease the amount of maintenance.


Note: Only a member of this blog may post a comment.