Sandboxing 101
In any non trivial, team oriented project you have multiple configurations:- team-member-one-sandbox, team-member-two-sandbox
- QA
- UAT
- PROD-Americas, PROD-Europe, PROD-Asia
- Etc
- Defaults
- PROD-Defaults
- Americas
- Europe
- Asia
- PROD-Defaults
.NET/MSBuild Solution
There are a couple of choices available:- T4
- MSBuild
- NAnt
- Custom PostBuild event scripts in Visual Studio
- An AdHoc combination of the above
- defaults.cfg
- prod-americas.cfg
- prod-europe.cfg
- prod-asia.cfg
App.config
<configuration> <appSettings> <add key="setting_one" value="${setting_one}"/> ${custom_settings} </appSettings> </configuration>
defaults.cfg
<settings> <x key="setting_one">Hello World From DEFAULTS!</x> </settings>
debug.cfg (ie dev/qa/uat/etc)
<settings> <x key="custom_settings"> <add key="custom_setting_1" value="This is DEBUG custom setting ONE."/> <add key="custom_setting_2" value="This is DEBUG custom setting TWO."/> </x> </settings>
release.cfg
<tokens> <settings> <x key="setting_one">Hello World From RELEASE!</x> <x key="custom_settings"> <add key="custom_setting_1" value="This is RELEASE custom setting ONE."/> <add key="custom_setting_2" value="This is RELEASE custom setting TWO."/> </x> </settings>
MSBuild Task Detail
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" /> <PropertyGroup> <ConfigOutDir>$(OutputPath)\cfg</ConfigOutDir> </PropertyGroup> <Target Name="ProcessConfig"> <Message Text="==>>>> CurrentEnvironment = $(EnvId)" /> <!-- BEGIN default (ie common) settings --> <XmlQuery XmlFileName="$(MSBuildProjectDirectory)\cfg\defaults.cfg" XPath="//settings/*"> <Output TaskParameter="Values" ItemName="DefaultSettingValues" /> </XmlQuery> <ItemGroup> <Tokens Include="%(DefaultSettingValues.key)"> <ReplacementValue>%(DefaultSettingValues._innerxml)</ReplacementValue> </Tokens> </ItemGroup> <!-- END defaults.config --> <!-- specific environment --> <XmlQuery XmlFileName="$(MSBuildProjectDirectory)\cfg\$(EnvId).cfg" XPath="//settings/*"> <Output TaskParameter="Values" ItemName="SettingValues" /> </XmlQuery> <ItemGroup> <Tokens Include="EnvId"> <ReplacementValue>$(EnvId)</ReplacementValue> </Tokens> </ItemGroup> <!-- Remove duplicates - this is important for "overrides" --> <ItemGroup> <Tokens Remove="%(SettingValues.key)" /> </ItemGroup> <ItemGroup> <Tokens Include="%(SettingValues.key)"> <ReplacementValue>%(SettingValues._innerxml)</ReplacementValue> </Tokens> </ItemGroup> <Message Text="Parsed Tokens => %(Tokens.Identity): %(Tokens.ReplacementValue)" /> <MakeDir Directories="$(ConfigOutDir)" /> <TemplateFile Template="$(MSBuildProjectDirectory)\app.config" OutputFilename="$(ConfigOutDir)\$(EnvId).app.config" Tokens="@(Tokens)" /> </Target> <Target Name="BeginProcessConfig"> <ItemGroup> <EnvConfigFiles Include="$(MSBuildProjectDirectory)\cfg\*.cfg" Exclude="$(MSBuildProjectDirectory)\cfg\defaults.cfg" /> </ItemGroup> <MSBuild Targets="ProcessConfig" Properties="EnvId=%(EnvConfigFiles.Filename)" Projects="$(MsBuildProjectFile)" /> <!-- Copy over the correct file based on configuration in visual studio or command line --> <PropertyGroup> <EnvConfigIn>$(ConfigOutDir)\$(Configuration).app.config</EnvConfigIn> </PropertyGroup> <Message Text="EnvConfigIn = $(EnvConfigIn)" /> <Copy SourceFiles="$(EnvConfigIn)" DestinationFiles="$(OutputPath)$(AssemblyName).exe.config" /> </Target> <Target Name="AfterBuild" DependsOnTargets="BeginProcessConfig"> <Message Text="This is the AfterBuild target: $(MSBuildToolsPath)" /> </Target>
Demo Project
1. Install MSbuild Common Tasks
http://msbuildtasks.tigris.org/
Note: the easy way to experiment is to just install via .msi installer, alternatively you can download the .zip file with all the binaries, but then you will have to configure the Import of msbuild tasks in the .csproj file - not difficult, and definitely something you want to do for self contain projects (typically you would include the binaries in some libs sub-folder of your project and reference it via relative paths from msbuild).
2. Download Source
View envcfgdemo-zip or if you behind an evil firewall: Download Demo Visual Studio 2008 Project
When opening the project you will be prompted with a dialog telling you that the project file is using some external extensions and whether you want to trust it. This is normal and you have to do it just once.
Try selecting different Configurations in Visual Studio, or run from command line with
msbuild /p:Configuration=CustomEnv
or
msbuild /p:Configuration=Debug
Note: all of the configurations are built and placed into bin\$(Configuration)\cfg folder, you can examine the files and sometimes it's useful for further automatic deployments (ie you can copy over the right config file via a script at the time you deploy vs build time).
No comments :
Post a Comment