views:

338

answers:

2

I am trying to change the database name in the connectionstring located in the App.Config of our servicehost at runtime and restart it afterwards connecting to another database. This works fine, but only if the application is shut down for multiple seconds. Shutting down the application for several seconds seems to clear the cache of the ConfigurationManager.Connectionstrings. The problem is that due to this required shutdown time, I can not use Application.Restart() in my application.

The strange thing about this caching behaviour is that even when the value is updated in memory (in the example the second time it is requested) the updated value is displayed correctly. But when the application is restarted the old value seems to re-emerge.

To verify the behaviour create a new console app.

add an App.Config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="DomainDBConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=InitialDBName;Integrated Security=SSPI;" />
  </connectionStrings>
</configuration>

then add the following code to the Main method

        ConfigurationManager.RefreshSection("connectionStrings");
        DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
        Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        builder.ConnectionString = appConfig.ConnectionStrings.ConnectionStrings["DomainDBConnectionString"].ConnectionString;

        //print initial value
        Console.WriteLine("initial " + (string)builder["Initial Catalog"]);

        //change value
        builder["Initial Catalog"] = "ChangedDatabaseName";
        appConfig.ConnectionStrings.ConnectionStrings.Remove("DomainDBConnectionString");
        appConfig.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings("DomainDBConnectionString", builder.ConnectionString));
        appConfig.ConnectionStrings.SectionInformation.ForceSave = true;
        appConfig.Save(ConfigurationSaveMode.Full);
        ConfigurationManager.RefreshSection("connectionStrings");

        Console.ReadLine();

        DbConnectionStringBuilder builder2 = new DbConnectionStringBuilder();
        Configuration appConfig2 = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        builder2.ConnectionString = appConfig.ConnectionStrings.ConnectionStrings["DomainDBConnectionString"].ConnectionString;
        Console.WriteLine("changed " + (string)builder2["Initial Catalog"]);

        Console.ReadLine();

To reproduce this behaviour, you need to run the application (by hitting F5) and close it. afterwards the solutionname.exe.config file will show up with the modified value. If you run the application a second time (this time by doubleclicking the solutionname.exe) you will notice the difference in behaviour if you do this immediately after terminating your application, or after you have waited a couple of seconds.

In my opinion the configsection should be re-read because of ConfigurationManager.RefreshSection("connectionStrings"); but apparenatelly this does not work as advertised.

A: 

The problem seems to reside in the fact that the first time, I run the application from visual studio (with debugger enabled).

If I run the application from the bin/debug directory the caching problem does not seem to exist.

For my production environment this will fix my problem (so in other words my problem is fixed). This however does not kill my curiousness of the cause of the difference in behaviour.

sjors miltenburg
A: 

2 Things:

First when you are in debug mode you are not using solutionname.exe.config; you are actually using solutionname.vshost.exe.config so thats why your iconsistent behavior because the solutionname.vshost.exe.config file goes back to the original version as soon as you stop the application; loosing any changes you made to it.

Seconds this line of code ConfigurationManager.RefreshSection("connectionStrings"); not always works as expected. I have found that some times is better to refresh parent section or section group; in this case would be "configuration".

so try ConfigurationManager.RefreshSection("configuration");

Darkonekt