3
votes

What I'm trying to do

Currently we have duplicate WCF config settings in several projects in our solution. I want to store the WCF config values in one file which can be then referenced from as many projects as necessary. The config file must transformable to allow for different values in different enviroments.

What I've tried

I've done some research other people have tried something similar with SlowCheetah and linked files. So this is what I've tried to do. It's worth noting that our solution contains a lot of projects, some MVC3, some console apps and some class libraries.

  1. I've created a Wcf.Client.config file, added it to a common class library and added transforms to it using SlowCheetah
  2. I want to reference this file in an MVC3 project so I've created a link to the config file
  3. In the web.config file of the MVC3 project I've added a group containing a client element with the configSource attribute set to "Wcf.Client.config"
  4. I've set the "Copy to output directory" property of the linked config file to "Copy if newer"
  5. I also added a transform to the linked file (I wasn't sure this would work but it succesfully linked the files)

The problem

I have transforms for local and development environments. Unfortunately when I run the web application (or publish it) in the developer configuration the transforms are not picked up. Looking at the pubished files I can see that the linked file that I placed in the root of the web project has been successfully transformed, but, it is read from the bin folder, and the file in the bin folder is not tranformed.

What am I actually asking?

What I really want to know is, what am I doing wrong? Has anyone tried what I've described above and made it work? Or failing that has anyone found another way to share transformed config files?

Some code

I've created a very simple test project which hopefully will explain what I'm trying to do better than my rambling explanation. Feel free to have a look. If you build or publish it you'll see the Wcf.Client.config file in the bin folder of the MVC3 project has not been transformed.

1
Phil, did you have any luck with this? We're looking to do something similar...Oskar Austegard
I'm afraid not. I didn't manage to get SlowCheetah to work as I wanted and I didn't manage to find another solution. Unfortunately I wasted quite a bit of time on the problem so I just had to make do with duplicate configs, which is rubbish, but they will rarely change so shouldn't cause any problems.Phil Hale
Can you try with the latest version, 2.5.1, which I just posted to visualstudiogallery.msdn.microsoft.com/…? Let me know if it doesn't work. I did a bunch of work for linked files about a month or two ago.Sayed Ibrahim Hashimi
I've retested it with 2.4.1 (I can't find 2.5.1 not sure if it's a typo) and unfortunately I'd had no luck. It still doesn't work.Phil Hale
I got this working. If you look at SlowCheetah.Samples/Wpf.Transform/Wpf.Transform.csproj in v 2.5.1 or later, you can see what how your linked config files should look in your csproj. I had to add the <TransformOnBuild> , <IsTransformFile>, and <CopyToOutputDirectory> elements to mine (on the project that linked to the configs in another project).sproc

1 Answers

2
votes

I found a suitable solution in this answer.

I've done the following steps:

1) I created the configuration in the solution directory. I named is CommonSettings.config

2) I added transformation configs CommonSettings.Debug.config, CommonSettings.Debug.config and a source config (since Microsoft's build task could't write to the source file for some reason) CommonSettings.Source.config

3). Then in a common class library (one which is referenced by all projects that require CommonSettings.config) I edited the project file by adding the following lines:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />

<Target Name="BeforeBuild">
    <CallTarget Targets="TransformCommonSettings" />
</Target>

<Target Name="TransformCommonSettings">
    <ItemGroup>
        <ConfigsToTransform Include="..\CommonSettings.config" />
    </ItemGroup>

    <TransformXml 
        Source="@(ConfigsToTransform->'%(RelativeDir)%(Filename).Source%(Extension)')"
        Destination="%(FullPath)"
        Transform="%(RelativeDir)%(Filename).$(Configuration)%(Extension)"
        Condition="Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)')" /> 
</Target>

4) Then I added the CommonSettings.config to my web application (and some windows applications and tests) as a Link. In the properties window I set Build Action to Content and Copy to Output Directory to Copy always 5) In my Web.config file after registering the commonSettings section I added the following line:

<commonSettings configSource="bin\CommonSettings.config" />

6) For Test projects and Console/Windows applications I set appropriate value in App.config:

<commonSettings configSource="CommonSettings.config" />

Here without bin in the path since both App.config and CommonSettings.config are copied to the output directory.

Now after building in my chosen configuration the CommonSettings.config is transformed correctly and the proper version is copied to the output directory.

The good part is that you don't need no SlowCheetah extension and it will work on your build server which is perfect for me if you include the task .dll :)

One problem is when you just Run a project (hit F5) the transformations will not run. I had to add this build task to all my project which slowed down the building process about a second but for me it's acceptable.