Saturday, March 07, 2009

Managing Environment Specific Configurations Settings at Install Time

I’ve been asked a few times in the past few weeks about approaches for managing environment specific settings in config files.  Over the years, I’ve seen this solved a few different ways, and I tend to like the following approach:

  • Create a Setup project in your solution.
  • Open the User Interface Editor, and add a 3-button dialog to the setup (right-click the Start folder and choose “Add Dialog” and pick the 3-button dialog option)
  • Right-Click the newly added entry in the “Start” windows tree and select “Move Up”, so that this window is somewhere before the “Conform Install” dialog.
  • Edit the Properties Window for the 3-buttons window to be something like the following:

SetupProject3Buttons

  • In your main project (UI, Console, etc), add an XML file for the environment specific settings.  The schema should be something like the following:

<environments>
  <
environment name="Development">
    <
setting settingKeyPath="<your xpath here..>" propertyName="<your property here..>" propertyValue="<your value here…>" />
  </
environment>
…….repeat the environment section for each targeted environment

</environments>

  • In your main project, add a new class and have it implement the “Installer” class (found in System.Configuration.Install – so you’ll probably need to add a project reference to that assembly).
  • Override OnAfterInstall, but make sure you first call base.OnAfterInstall(), then start the process of applying your settings from the XML file created earlier to the config file of your installing application.
  • Your environment setting can be pulled from Context.Parameters[“ENVIRONMENT”]
  • Write yourself some code to read in the data in the XML file, and overwrite the appropriate settings in the config file.

That’s the basic steps I take to manage environment specific config file settings in my VisualStudio projects.

VS2008 Database Project Deployment Script Failures

On my current project, we’re using a database project to allow us to manage our schema changes. This has helped us keep all of our dev and build boxes in sync, and things are moving along smoothly.

However, there is one quirk that seems to burn me every few weeks. When we have a script failure, I scan through the output window to see where things went wrong. The IDE is even nice enough to let you click through to the failing line so you can figure out where things went wrong.

That’s nice and all, but the script that gets opened is the deployment script, not the actual .sql file that you created earlier. So, I end up making the change and rebuild/deploy only to get the same error, again. By now, when I review the output and realize what I did, I locate the actual post-deployment script file and make my edits there, rebuild/deploy and things work just fine.

How difficult would it have been to make the generated deployment script read-only so I wouldn’t keep getting burned by this quirk? Better yet, why not take me to the actual script file that caused the problem in the first place?