views:

1197

answers:

6

Is there a way to override a ConnectionString in an app.config. Our buildsystem runs also on a server of a customer, but there the connectionString needs to be different. Because the app.config is in svn, everytime I change something in the app.config and commit it, I need to go to the server of the customer to change the connectionString back to their database...

In ant-scripts for example, this is no problem, but in an app.config I can't seem to find a way. Tried this for example:

<connectionStrings configSource="WebConnectionString.config">
  <add name="ConnectionString"
    connectionString="..." 
    providerName="System.Data.SqlClient"/>
</connectionStrings>

What I'm trying to do is that if WebConnectionString.config exists, then use the connectionString in that config file. If it doesn't, use the one defined in code sample (so, in app.config).

A: 

When we do a build we replace the SVN config with a production config, we've also moved to make the connection strings entirely web service based with all apps regardless of status pointing to a connection string web service that pulls the correct ones down.

Lloyd
Indeed, that's also what we do for the site, but this is for my unit tests. Guess I could do it the same way, but it would mean a lot of work. So, this is my only option?
Lieven Cardoen
We group connection strings by category, so we can for example say:GetConnectionString("UnitTests","ReportsDB");And in production:GetConnectionString("Production","ReportsDB");
Lloyd
+1  A: 

You could do this using the configSource attribute, but you would have to have one for each platform/environment, because the element has to be empty when using this feature:

However, when you use the configSource attribute, you must move the entire section to the separate file because there is no merging of element settings.

It's only the AppSettings section that allows you to override values like this with the file element.

Something to think about: VS2010 has a feature that allows you to modify the config files based on build target (live/release/debug/test etc).

Zhaph - Ben Duguid
Yes, but that leaves me with the same problem. If I commit the configSource file, I have the same problem. But it is an option not to commit it.
Lieven Cardoen
Yes, using this method, you'd have to not check-in the configs, which understandably may be an issue.
Zhaph - Ben Duguid
A: 

One approach is to use a Web Deployment Project to replace the connectionStrings section in web.config at build time. You could have a debug mode that uses your connstrs, and a release mode that leaves them unchanged. Everything can be fully checked-in to svn. You can also use WDPs to apply other custom post-build steps, which can be very handy.

Another option is to move them entirely into appSettings -- but that file only holds name/value pairs, so it would take a code change.

RickNZ
+2  A: 

WEB DELPOYMENT PROJECTS WOOHOO

What a way to save yourself loads of deployment grief. The one amazingly wonderful beautiful thing you can do is have a Build configuration for each customer.

Then you can also have a config file for each customer which contains the connections strings. Depending on which build configuration you choose the different connectionstrings will be pasted into the web.config. So now you can build a 'different' site for each customer it's soo easy.

Imagine a folder called config and files like cust1ConnectionString.cfg, cust2... etc

Now you create configurations. You are already familiar with Release and Debug, create cust1, cust2.

Then in the web deployment project there is an option to replace secions of the web config with sections from another file.

So you go to cust1 deployment and tell it that the connection string are in the file cust1connectionstrings.cfg. Tell it where cust2 is etc....

And now no more pissing around, everytime you build the site for a customer all there settings are inserted into the web.config and you can just hand over a correctly configured site. It doesn't matter what's in SVN cause each customer has there own config. Sweet

Robert
+2  A: 

Hi,

You could do following, create a class where you encapsulate the retrieval of the connection string.

something like this

public static class ConnectionStringBuilder
    {
        const string ConnStringDefault = @"defaultConnString";
        static readonly string _connString = string.Empty;
        public static string Build()
        {
            return _connString;
        }

        /// <summary>
        /// Builds connection string from the config file with the given name
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public static string Build(string name)
        {
            if (ConfigurationManager.ConnectionStrings[name] != null)
                return ConfigurationManager.ConnectionStrings[name].ConnectionString;

            throw new ArgumentException("Connectionstring with given name '" + name +"' not found! ", "name");
        }

        /// <summary>
        /// Initializes the <see cref="ConnectionStringBuilder"/> class.
        /// </summary>
        static ConnectionStringBuilder()
        {

            if (ConfigurationManager.ConnectionStrings["default"] != null)
            {
                log.Info("conn string in config found");
                _connString = ConfigurationManager.ConnectionStrings["default"].ConnectionString;
            }
            else
            {
                log.Info("no default connection string found, using test connection string");
                _connString = ConnStringDefault;
            }
        }
    }

and the usage would be something like this

using(var conn = new SqlConnection(ConnectionStringBuilder.Build())
   {
      // do some stuff...
   }

hope that helps

nWorx
A: 

I would move my connection strings to machine.config. This way you never have to worry about changing anything as they are all stored/managed on the server itself. You can now push new builds worry-free ensuring that all connection strings remain the same as they were originally setup.

jcm