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.
ConfigurationManager.ConnectionStrings references a specific section of your app config where are stored the informations to access your databases (one or more).
It is important to realize that the entire <appSettings> section is read, parsed, and cached the first time we retrieve a setting value.
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 inconsistent 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");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With