Is it possible to modify the connectionstrings defined in the app.config/web.config at runtime? I want to use different configfiles depending on the machine the app/site is run on (only for debugging purposes, of course. We'll use the regular config files when deployed).
I can write AppSettings, but not ConnectionStrings (AFAIK). Or can I?
Yes it's possible, but AFAIK only via Reflection. The following code should do what you need (read below for usage):
public static string SetConnectionString(Type assemblyMember,
Type settingsClass,
string newConnectionString,
string connectionStringKey)
{
Type typSettings = Type.GetType(Assembly.CreateQualifiedName(assemblyMember.Assembly.FullName, settingsClass.FullName));
if (typSettings == null)
{
return null;
}
PropertyInfo prpDefault = typSettings.GetProperty("Default", BindingFlags.Static | BindingFlags.Public);
if (prpDefault == null)
{
return null;
}
object objSettings = prpDefault.GetValue(null, null);
if (objSettings == null)
{
return null;
}
// the default property, this[], is actually named Item
PropertyInfo prpItem = objSettings.GetType().GetProperty("Item", BindingFlags.Instance | BindingFlags.Public);
if (prpItem == null)
{
return null;
}
object[] indexerName = { connectionStringKey };
string oldConnectionString = (string)prpItem.GetValue(objSettings, indexerName);
prpItem.SetValue(objSettings, newConnectionString, indexerName);
return oldConnectionString;
}
assemblyMember
is the calling type
settingsClass
is the type of your settings class
newConnectionString
is the full string to set
connectionStringKey
is the name of the connection string that you defined in your app's settings
You should call this method as soon as possible after your app has started, preferably in the Main() method.
I tried this once in my project for debugging purpose but could not do it, the problem (I guess, correct me if I am wrong) is on app start up the app.config gets loaded into the memory, any changes to app.config while the app is running do not get reflected.
To overcome this here's what I did, define all the connectionstrings in the app.config and then call the ones that you want when your program is running like this.
for example lets assume you defined your connectionstrings in the app.config as follows.
<connectionStrings>
<add name="YourNameSpace.Properties.Settings.ConnectionString_1"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=|DataDirectory|\file.mdb"
providerName="System.Data.OleDb"/>
<add name="YourNameSpace.Properties.Settings.ConnectionString_2"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=|DataDirectory|\file.mdb"
providerName="System.Data.OleDb"/>
</connectionStrings>
define as many as you want (you are debugging right :-) )
then to call those connection settings in your code do something like this:
YourNameSpace.Properties.Settings foo = new YourNameSapce.Properties.Settings();
foo.ConnectionString_1;
HTH
Best Regards
@nand
P.S: This reply is specific to C#.
This article goes into detail on the options you have: http://aspalliance.com/820
You can't really edit the config file of the running process.
One option (with pros and cons) is to use config data in the machine.config or the master web.config (for "site", you use the "location" nodes) - not an option to rush into, though.
A better way to handle this is to swap the config file as part of your build/deploy process, ideally automated. That way, everything is self-contained, and you can "robocopy" to a vanilla server and have it work.
Re your "per developer" point; I found that the easiest way to do this was to standardise the config, and tweak the machines. For example, we run a local web-server on a VM; rather than code against each machine, we standardise on "localserver" (to mirror "localhost"), and add a local DNS record to each machine that the developer can control. Note that this requires fixed IP addresses (or maybe a DHCP reservation) to prevent it changing over time!
Ditto databases; local servers can use "."; remote servers can be aliased on the machine, so "devserver" points to whatever the user wants.
Just a thought...
You could run xmlpoke in a NAnt script when installing the website.
E.g.
- Deploy the NAnt with the website.
- Create a go.bat that calls NAnt which installs the site and does xmlpoke to modify the web.config with settings based on the server name or some other parameter.