(This post relates to .net 2.0)
Like many developers, I have a development server, and a release server.
My websites usually have a DLL class library that hold the data access functionality, and when I create a TableAdapter, visual studio will store the connection string in the Settings file for that library.
The old way (copy and paste)
The problem I had was that the connection string would be different for the development (Debug) build and the release build of the website. My original workaround involved some scripts in an msbuild file that copied a stored version of the settings file that contained either the Debug or Release connection string over the top of the of the live Settings file.
MyBuild.msbuild snippet:
<Target Name="Settings_Debug">
<Copy SourceFiles="c:MyLibrarySettingsDebugSettings.settings" DestinationFolder="c:MyLibraryProperties">
<Copy SourceFiles="c:MyLibrarySettingsDebugSettings.Designer.cs" DestinationFolder="c:MyLibraryProperties">
<Copy SourceFiles="c:MyLibrarySettingsDebugapp.config" DestinationFolder="c:MyLibrary\">
</Target>
<Target Name="Settings_Release">
<Copy SourceFiles="c:MyLibrarySettingsReleaseSettings.settings" DestinationFolder="c:MyLibraryProperties">
<Copy SourceFiles="c:MyLibrarySettingsReleaseSettings.Designer.cs" DestinationFolder="c:MyLibraryProperties">
<Copy SourceFiles="c:MyLibrarySettingsReleaseapp.config" DestinationFolder="c:MyLibrary\">
</Target>
<Target Name="Build_Debug" DependsOnTargets="Settings_Debug">
<MSBuild Projects="c:MyLibraryMyProject.sln" Targets="Clean; Rebuild" Properties="Configuration=Debug"></MSBuild>
</Target>
<Target Name="Build_Release" DependsOnTargets="Settings_Release">
<MSBuild Projects="c:MyLibraryMyProject.sln" Targets="Clean; Rebuild" Properties="Configuration=Release"></MSBuild>
</Target>
Command line usage (from the Visual Studio Command Line)
msbuild MyBuild.msbuild /t:Build_Release
or
msbuild MyBuild.msbuild /t:Build_Debug
My actual msbuild file also does things like zip the website output for uploading to the webserver (where I have another script to backup the current website files and unzip the uploaded zip file for deployment), and also contains nunit tests for use with CruiseControl.net
This has been working ok for a few months, but it's been bugging me that if I change something in the settings file, I need to create new Debug and Release copies. Also, I would prefer it if the settings were changed in code, rather than relying on what is effectively a "copy and paste" mode of operation. It doesn't document very well if you are looking at the code - you need to dig into the msbuild file to work out what is going on.
Changing the settings in code
Anyway, after a bit of research, I've discovered that you can change the settings dependent on build type.
When viewing the settings, click the button that says View Code. This will create a Settings.cs file
In the constructor, add the following:
this.SettingsLoaded +=
Then press [TAB] twice - this will create the following code:
{
this.SettingsLoaded += new System.Configuration.SettingsLoadedEventHandler(Settings_SettingsLoaded);
}
void Settings_SettingsLoaded(object sender, System.Configuration.SettingsLoadedEventArgs e)
{
throw...
}
When the settings are first loaded, this event handler is called.
Now you can replace the
throw with the code to change your connection strings.
Using conditional compilation, we can enter the correct connection string.
#if (DEBUG)
this["MyConnectionString"] = "Data Source=myDevelopmentServer;Initial Catalog=MyLocalDatabase; Persist Security Info=True;User ID=aDevUser;Password=aPassword";
#else
this["MyConnectionString"] = "Data Source=myLiveServer;Initial Catalog=MyLiveDatabase; Persist Security Info=True;User ID=aLiveUser;Password=aPassword";
#endif
Note that you have to use the form
this["MySetting"] = "abc" rather than the more useful this.MySetting = "abc" as the latter is read-only.
Conclusion
To me, changing the connection string in code dependant on the build type is a much easier to understand and document. One of my projects has 4 build types (project configurations):
Debug,
Release, Test and
Demo - the
test build goes of to a test server and test database, the
Demo connects to the client's Demonstration database (rather than their live database). In these cases, I have added some Conditional complation symbols (found on the Build tab of the library properties) - just enter the word. My Settings_SettingsLoaded() now looks more like this:
#if (LOCAL) //a conditional compilation symbol defined in the "Debug" project configuration
this["ConnStr"] = "...DevServer...";
#elif (DEMO) //defined in the "Demo" project configuration
this["ConnStr"] = "...DemoServer...";
#elif (TEST) //defined in the "Test" project configuration
this["ConnStr"] = "...TestServer...";
#elif (LIVE) //defined in the "Release" project configuration
this["ConnStr"] = "...ReleaseServer";
#endif
I still use the msbuild file to select the correct build for the target, but I no longer use the msbuild to copy and paste files around.
[tags].net, c#, visual studio [/tags]