How can I get ConfigurationManager to load application settings from multiple files? - c#

I'm writing applications that interoperate with a third-party application. This application exposes an API to developers via methods in a DLL. Some time ago, the vendor of this app started integrating their own .NET components into their program, and when they did, they decided that their components should use the ConfigurationManager to get settings at runtime.
What this means: their program, foo.exe, calls fooengine.dll, and it reads its settings from foo.exe.config. My program, bar.exe, also calls fooengine.dll, and it reads its settings from bar.exe.config.
Well, that's just plain wrong. But how do I fix it?
The simple workaround is to replicate foo.exe.config's settings in bar.exe.config. That'll work, but it's stupid. It means that from an administrative standpoint, a given setting has to be maintained in N different files. That's going to fail sooner or later.
I tried putting a configSource attribute on the appSettings section in my config file. (As it happens, I'm using the applicationSettings section for my settings, and they're using the appSettings section for theirs, so I can live with simply getting that section from a different file.) But the ConfigurationManager doesn't like that: it wants the path in configSource to be not only relative to but below my program's directory.
I can physically read their settings file into an XmlDocument and then set them myself. But now I'm tightly coupling my code to their implementation; if they put out a new release that moves the settings to the applicationSettings section (which is where they should be now that it's 2009), my code will break.
Is there another way out of this?

Okay, I think I've found the answer, at least for my specific version of this problem.
The .NET 2.0 ConfigurationManager supports a file attribute on the appSettings element. This lets you get the contents of that element from an external file. So what I do is:
Cut the appSettings element out of foo.exe.config and paste it into another file in that directory called, let's say, appSettings.xml.
Add a new element to foo.exe.config: <appSettings file="appSettings.xml"/>.
Add an element to bar.exe.config: <appSettings file="c:\program files\foo\appSettings.xml"/>
This works. But it only works because my program doesn't use appSettings at all.

You could just load their configuration file.

Related

Is it possible to serialize changes in your application configuration to your application's app.config file?

Is there a built-in mechanism for serializing changes to your app.config file using built-in functions available in .NET?
For instance, if I have a custom property set in Executable.exe.config that changes during runtime, I would like .NET to update the Executable.exe.config accordingly.
I know I could do this by creating my own serialization mechanism, but would like to know if it's possible using functionality already available in .NET by default.
You can use the ConfigurationManager class.
There are a lot of sample on the link above or on this article that also provides a short sample.. You need to add a reference to System.Configuration, and basically, you access and save the file like this:
// Open App.Config of executable
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Do stuff
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
In order to force your program to immediatly take the refreshed data, you need to refresh the section using the ConfigurationManager.RefreshSection method
// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
And an important note from this thread, for those that say that it doesn't work in debug mode:
If you are running the code from the debugger (within VS) than your
code is actually changing the YourAssemblyName.vshost.exe.Config If
you start YourAssemblyName .exe directly from the bin\debug folder it
will change YourAssemblyName.exe.Config

Settings For Individual Programmers In A Config File

I'm wondering if there is a way to create settings in a config file for individual programmers. The situation I'm encountering is that there are some programmers who want settings turned on and several that want them turned off. Our config files are in SVN source control, so using a shared config file means we are always overwriting each others settings. We are doing this for an ASP.NET web application project. My initial thoughts would be to create a config file outside of source control, but how do I make it so that each programmer has his own copy?
Here is some further clarification. We have a link in the main web.config file that points to an environment-based file (e.g. file used for dev, staging and live).
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings configSource="EnvironmentConfigs\appSettings.config" />
...
</configuration>
Inside the appSettings.config file, we have settings for dev, staging and live. What I'd like to do is create another config file called user.config and have the individual programmer settings staored there (not in source control of course). What do I need to do in order to have visual studio read from this new file?
The settings file does not need to be versioned in SVN, or each developer can select their settings file to not be overwritten or committed. See the SVN settings file, it could even be added as a global ignore.
Each developer can set up their own build congifuration in Visual Studio. This build configuration should be linked to a build script, which replaces sections of the Web.Config/App.Config/*.Config files specifically as the developer wants.
This way, when they want to make changes to the config files to suit themselves, they should change the replacements in the build script rather than changing the config file directly.
This article covers some of the points i've mentioned: http://www.diaryofaninja.com/blog/2010/05/09/automated-site-deployments-with-teamcity-deployment-projects-amp-svn
Remove the config file from source control and set the svn:ignore property on it. Then it won't be committed. Then, also create another file, like, Production.web.config, that has the production values in it, so you still keep those around too.
That's what I do!
Don't commit config file changes unless they are new settings that to be sent to everyone.
Otherwise, checkout, edit, and leave it checked out. You'll know if someone else has added/modified the file when you get latest version. At which time you merge your settings with their changes, but leave it checked out on your machine.
We do not store application configuration files in source control. Instead, in source control, we store a configuration file template, usually named something like web.config.template. Each developer has their own 'values' file, usually named web.config.values-bem for instance. Each developer also sets up a post-commit hook which takes the template file, and processes it, replacing 'variables' with their values from the specified values file.
For instance, my config values file has the following definition in it:
DB_SERVER=.\SQLEXPRESS
In the web.config.template file, this exists:
connectionString="server=#DB_SERVER#[DEV1];Persist Security Info=True;Password=#DB_PW#;User ID=#DB_USER#;database=#DB_NAME#;Enlist=false;Max Pool Size=100" />
So when the process runs (a python script), it replaces all instances of #DB_SERVER# with the setting I have in my values file. The template script allows for default values to be specified right in the template as well, so you can make changes to the template file and not break other developers' environments (usually). (The default values are next to the variable, in square brackets.)
This solution allows each developer to have their own settings, but still have a web.config.template file that's versioned, and each developer avoids 'inflicting' configuration changes on other developers.
This works well for us. If you want to use the same scheme, you can check out the code for it on my github: https://github.com/bmontgomery/FileReplace. I can help you with the hook scripts as well if you're interested in that.

How to go about creating a configuration file for my application in .NET

I am working on a software and want to create a configuration file for my application to store configurations that will be used at runtime. I have seen some software use a config.xml file to achieve this. The configuration file I want to use will have:
Cache folder location
Color scheme
Option to toggle caching
How to go about this? I am working with WPF.
In Visual Studio, add an "app.config" to your project. When you build your application, this will create an AppName.exe.config file, where AppName is the name of your executable. This is an XML config file that can contain your settings.
If theses options are user-specific, don't use app.config - that's for global application settings and you will clobber other users' settings. I'm bringing this point up because you mentioned caching options in your question, and in some applications, the choice to cache or not to cache is at the user level.
Instead, I would recommend that you create a domain object to store the configuration settings to, and serialize the object to a local folder in the current user's isolated storage folder.
When the application starts up, just look into the current user's isolated storage folder, confirm the serialized file exists, and deserialize back to the domain object.
as you are in WPF world, you also can use App.XAML for defining and using color schemes
Use standard .NET settings framework.
More details here: How is the logic behind storing program setting in text file like 'config.cfg'?
Also this will help http://msdn.microsoft.com/en-us/library/aa730869%28v=vs.80%29.aspx.
Although this article is a little old, not much changed since then in this realm.

Change in AppSettings needs restart my Application how can I avoid?

I'm using C# .NET 2.0 Windows Application.
and I'm using app.config for my Application Settings.
but change in AppSettings doesn't reflected runtime, it Needs Application to be restarted.
How can I avoid it.
Here is my code snippet I used to read and write the Application Settings.
I'm reading the Setting like this
string temp = ConfigurationManager.AppSettings.Get(key);
I'm updating the value like this where node is the current configuration/appSettings Node
node.Attributes["value"].Value = value;
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
You could try calling ConfigurationManager.RefreshSection("appSettings") to refresh the AppSettings section of the file from disk. Once they have been refreshed, you should be able to read the new values.
I've just tested this and it does indeed work.
Alternatively, you could create a singleton 'Options' to hold on to your application settings and perform your read/writes for you. Once loaded, changing the .config doesn't require reloading, you simply set a property on the singleton and call your .Save() method.
The 'runtime' version of your settings is in the singleton, no need to read from disk.
Dont use ConfigurationManager to read settings, instead use:
System.Configuration.ConfigurationManager.OpenExeConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile).AppSettings.Settings["value"];
ConfigurationManager.RefreshSection("appSettings");
works!!
But be careful that if we are in debug mode, the configuration file can be called xxxxx.vshost.exe.config, where xxxxx is your project name.

How can I store user-tweakable configuration in app.config?

I know it is a good idea to store configuration data in app.config (e.g. database connection strings) instead of hardcoing it, even if I am writing an application just for myself. But is there a way to update the configuration data stored in app.config from the program that is using it?
If you use the Settings for the project, you can mark each setting as either application or user.
If they're set as user, they will be stored per-user and when you call the Save method it will be updated in the config for that user.
Code project has a really detailed article on saving all types of settings.
app.config isn't what you want to use for user-tweakable data, as it'll be stored somewhere in Program Files (which the user shouldn't have write permissions to). Instead, settings marked with a UserScopedSettingAttribute will end up in a user-scoped .config file somewhere in %LocalAppData%.
I found the best way to learn this stuff was to mess with the Visual Studio "Settings" tab (on your project's property pages), then look at the code that it generates and look in %LocalAppData% to see the file that it generates.

Categories