Where to store config information?

  • Thread starter Thread starter James Crosswell
  • Start date Start date
J

James Crosswell

So it used to be that this info went in ini files... then it was the
registry and now it seems that it's gone back to files again with the
introduction of .config files to facilitate xcopy deployment.

However, I'm still pretty confused about where everything should go. It
seems that with Windows Vista we can't write to directory in which the
application is located - so I'm wondering where this stuff should go in
various different situations.

For example, I have a NT Service application and a GUI tool to configure
that NT Service. The GUI config tool will typically be run by Joe Schmoe
and will need to write our various settings to configure the operation
of the NT Service, which will likely be running in the security context
of the Local System or Network System account. So, if Joe writes
settings to one of his user directories then that's not too much use. On
the other hand, from what I understand Joe won't have access to write to
the program directory either - so where/how should the configuration
settings for this NT Service be read/written by the GUI tool that Joe
runs, such that they can then be read/used by the NT Service that
they're destined for?

In another situation, I have a middle tier application server which will
be running under IIS. I'm presuming here that I can use different
sections in the web.config file to store application specific data -
correct?

And then, in the simplest of all situations, there's the standard
Windows Forms app, in which case there are two kinds of config information:
1) Application specific config info -like database connection strings etc.
2) User specific config info - like persistence information for
window/dialog positions and options.

I'm wondering which classes in the .NET Framework I'd use to write the
former and which I'd use to write the later (and if possible I'd like to
track down some sample code for both).

Is there a comprehensive guide somewhere as to where we should be
storing dynamic config info in each of the different situations above?

Thanks in advance for any help with this.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
Adriano said:
When you us a .NT service you should write a .config file in the same dir
where your service is installed and be sure that the user running the service
has the right privileges to access the dir (are you using the
ConfigurationManager class? This is a must with VS2005!).

Thanks Adriano - I guess I'll have to oblige system administrators to
configure the NT Service, which is almost always the case with the
product I'm writing anyway.

I am trying to use the ConfigurationManager class but it's kind of
complex for what initially appears to be a simple task. I have various
different "modules" for this app and I'd like each module to store it's
configuration information in a separate SectionGroup within the config file.

I saw some quite good code demonstrating how to do this in .NET 1.1
(very simply) but haven't found any examples for .NET 2 that write
settings anywhere but to the AppSettings... I'd like to write stuff to
Custom sections (otherwise there's going to end up being an aweful lot
of stuff in the root AppSettings)... Ideally I'd like:

<configuration>
<appSettings>
...general app settings here
<modules>
<moduleName>
... finally all the config info here </moduleName>
</modules>
</appSettings>
</configuration>

Writing the general app settings seems simple enough - they're just
name/value pairs. I haven't bumped into any xpath functionality in the
ConfigurationManager class/subclasses yet though (I'm sure I'm just
looking in the wrong places).

Thanks again for your reply.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
Adriano said:
If you have this file:
<configuration>
<appSettings>
<add key="ABCD" value="Hello" />
</appSettings>
</configuration>

What did you have to do in version 1.1 was, like an example:

string xxx = ConfigurationSettings.AppSettings["ABCD"]

but it's now obsolete; instead you must use:

NameValueCollection AllAppSettings = ConfigurationManager.AppSettings;
string xxx = AllAppSettings["ABCD"];

or

NameValueCollection AllAppSettings = ConfigurationManager.AppSettings;
string xxx = AllAppSettings[0];

Let me know if you need more.

Regards, Adriano Palmieri.

Thanks Adriano, but that's not what I'm trying to do though (I've seen a
million examples of doing just that). What I'm trying to do is store
settings somewhere OTHER than the root appSettings branch... So imagine
I want to be able to read/write ot the setting ABCD below, do you know
how I'd do that?

<configuration>
<settings>
<modules>
<myModule>
<add key="ABCD" value="Hello" />
</myModule>
</modules>
</settings>
</configuration>


I've seen examples of how to do so in .NET 1.1, such as:
http://www.codeproject.com/csharp/app_config.asp

But I can't find anything on how to do the same using the new
ConfigurationManager class.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
Hi James,
what are you trying to do is not standard and absolutely not suggested on
Microsoft practice (at least for what I've been told for my MCTS). You can
read the config file that you want by hand using xml statement but I highly
suggest you to use the standard Microsoft structure, meaning go and use the
AppSettings or UserSettings, even if in there you have to use a special
handmade class to manage your stuff. When you specify the Settings in VS2005,
you can specify every object present in the framework like a parameter and
this include your personal class to manage the settings; this class must
inherit from ApplicationSettingsBase.
I'll build an example as fast as I can and I'past it to you.

Regards, Adriano Palmieri.

James Crosswell said:
Adriano said:
If you have this file:
<configuration>
<appSettings>
<add key="ABCD" value="Hello" />
</appSettings>
</configuration>

What did you have to do in version 1.1 was, like an example:

string xxx = ConfigurationSettings.AppSettings["ABCD"]

but it's now obsolete; instead you must use:

NameValueCollection AllAppSettings = ConfigurationManager.AppSettings;
string xxx = AllAppSettings["ABCD"];

or

NameValueCollection AllAppSettings = ConfigurationManager.AppSettings;
string xxx = AllAppSettings[0];

Let me know if you need more.

Regards, Adriano Palmieri.

Thanks Adriano, but that's not what I'm trying to do though (I've seen a
million examples of doing just that). What I'm trying to do is store
settings somewhere OTHER than the root appSettings branch... So imagine
I want to be able to read/write ot the setting ABCD below, do you know
how I'd do that?

<configuration>
<settings>
<modules>
<myModule>
<add key="ABCD" value="Hello" />
</myModule>
</modules>
</settings>
</configuration>


I've seen examples of how to do so in .NET 1.1, such as:
http://www.codeproject.com/csharp/app_config.asp

But I can't find anything on how to do the same using the new
ConfigurationManager class.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
Adriano said:
what are you trying to do is not standard and absolutely not suggested on
Microsoft practice (at least for what I've been told for my MCTS). You can

Hm, well it might not be suggested but putting everything in appSettings
without making any grouping/sections is analogous to putting all the
files on a computer in the root directory of the C drive... which I'm
not about to do - it's a management nightmare... so if it's not yet
suggested then someone should suggest it to them.

Regardless, I have multiple modules and there may well be two modules,
both with a settings called "Foo"... so I want to keep this information
in separate SectionGroups (even if these SectionGroups are under nested
inside the appSettings tags - I don't particularly care where they are
but they MUST be heirarchical). So the following would be fine also:

<configuration>
<appSettings>
<modules>
<myFirstModule>
<add key="ABCD" value="Hello" />
</myFirstModule>
<mySecondModule>
<add key="ABCD" value="Hello" />
</mySecondModule>
</modules>
</appSettings>
</configuration>

It's a bit bizarre really - it looks like the new ConfigurationManager
class is a lot less powerful and flexible at handling these XML config
files than the old ConfigurationSettings class. By why would anyone
depricate a class that is more powerful than the alternative that
they've replaced it with??? I don't think they would, so it must be
possible to create groups/hierarchies of settings in the app config file
using the new ConfigurationManager class somehow.

If not then I'll have to either go back to using the deprecated class or
write my own classes to read/write settings to the app config file
directly using the raw XML classes and xpaths.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
This is another answer Jeff, cause what are you tring to do is not using a
config file (in the way it meant to be, Microsoft speaking) but using your
XML formatted config file. So let's say you have this config file, located
like usual in the exe directory of the project and with the conventional name:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<settings>
<modules>
<myModule>
<module1 name="mod1" param="Hello1" />
<module2 name="mod2" param="Hello2" />
<module3 name="mod3" param="Hello3" />
</myModule>
</modules>
</settings>
</configuration>

just use simple XML DOC to access it and it's done:

Configuration cs =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(new FileStream(cs.FilePath, FileMode.Open));
if (xdoc.HasChildNodes)
{
XmlNode xnode =
xdoc["configuration"]["settings"]["modules"]["myModule"]["module1"];
XmlAttribute xName = xnode.Attributes["name"];
XmlAttribute xParam = xnode.Attributes["param"];

Console.WriteLine(xName.Name + " - " + xName.Value);
Console.WriteLine(xParam.Name + " - " + xParam.Value);
}

Console.ReadLine();

try it on and let me know.

Regards, Adriano Palmieri.

James Crosswell said:
Adriano said:
If you have this file:
<configuration>
<appSettings>
<add key="ABCD" value="Hello" />
</appSettings>
</configuration>

What did you have to do in version 1.1 was, like an example:

string xxx = ConfigurationSettings.AppSettings["ABCD"]

but it's now obsolete; instead you must use:

NameValueCollection AllAppSettings = ConfigurationManager.AppSettings;
string xxx = AllAppSettings["ABCD"];

or

NameValueCollection AllAppSettings = ConfigurationManager.AppSettings;
string xxx = AllAppSettings[0];

Let me know if you need more.

Regards, Adriano Palmieri.

Thanks Adriano, but that's not what I'm trying to do though (I've seen a
million examples of doing just that). What I'm trying to do is store
settings somewhere OTHER than the root appSettings branch... So imagine
I want to be able to read/write ot the setting ABCD below, do you know
how I'd do that?

<configuration>
<settings>
<modules>
<myModule>
<add key="ABCD" value="Hello" />
</myModule>
</modules>
</settings>
</configuration>


I've seen examples of how to do so in .NET 1.1, such as:
http://www.codeproject.com/csharp/app_config.asp

But I can't find anything on how to do the same using the new
ConfigurationManager class.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
Adriano said:
This is another answer Jeff, cause what are you tring to do is not using a
config file (in the way it meant to be, Microsoft speaking) but using your

Hi Adriano,

Are you certain about what the "standard practices" are here? What
you're saying is that Microsoft discourage using the config file in a
hierarchical manor and instead that all settings should be read/written
in one place without any attempt to grouping or organize these further?

I haven't read anything that suggests that anywhere. I've read lots of
simple examples of using ConfigurationManager to read/write key/value
pairs to the appSettings section of the config file, but that's not to
say that the use of groups, hierarchies or sections is frowned upon - in
fact there seems to be quite a lot of support for exactly this built
into the Configuration namespace - I'm just having difficulty tracking
down any useful examples of such.

For example, the ConfigurationManager.GetSection method? This was
obviously included for some reason no? And it wasn't included because
Microsoft discourage it's usage... so there is indeed an "approved"
method of accessing Custom Sections built into the framework.

Another example is the Configuration.SectionGroups property - it seems
clear to me from the very existence of this property that the Microsoft
engineers envisaged people breaking the settings that they stored in
config files down into more manageable chunks (SectionGroups)...

Thanks for your help in any case, but I think I'll keep searching on
google.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
So I finally found some decent documentation on this:
https://secure.codeproject.com/dotnet/mysteriesofconfiguration.asp

To be honest, what I was hoping would be a couple of lines of code
appears to require writing literally pages and pages of code to define
classes and then some fiddling around writing changes (in XML) into the
app config file.

It's amazing that a task which used to consist of :
create instance of ini file class
read/write datetime/string/int/bool to particular section
release instance of ini file class

(literally three lines of code - 6 with a try finally block) has now
become a process that an experienced programmer could very well waste
5-10 minutes on... and a process that he/she will undoubtedly have to
replicate many times during the development of any project, potentially
wasting hours of his/her time.

So the new ConfigurationManager class seems to be, in brief, a major
disappointment in terms of it's versatility and usability. It's quite
nice if all you want to do is store a name/value pair or a
ConnectionString but as soon as you want to organize your configuration
information (even just into sections like with ini files) it chokes
productivity completely.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
I think I've finally nutted it out. The link in the post above describes
a pretty full/complete way of building a set of classes to give you
strongly typed access to config information - but this isn't strictly
necessary. The following code can be used to get at any xpath section in
the App.config XML configuration file:

NameValueCollection modConfig =
(NameValueCollection)ConfigurationManager.GetSection("modules/admin");

Then all that needs to be done is to add the following to the config file:

<configSections>
<sectionGroup name="modules">
<section name="admin"
type="System.Configuration.NameValueSectionHandler" allowLocation="true"
allowDefinition="Everywhere"/>
</sectionGroup>
</configSections>
<modules>
<admin>
<add key="SomeProperty" value="Foo" />
</admin>
</modules>

Basically, this makes use of the existing NameValueSectionHandler which
avoids the need to write your own handler, so the upside is that it
saves writing pages and pages of code and allows the use of adhoc
settings in a custom section. The down side is that it only handles
string values, so it's not strongly typed.

Best Regards,

James Crosswell
Microforge.net LLC
http://www.microforge.net
 
Back
Top