Cracking ConfigurationManager

J

Jonathan Wood

This is crazy. Does anyone have a simple example of reading a variable from
the application config file for a desktop application?

I've spent way too much time on this. I've found huge examples and lots of
help topics. But the .NET help topics are beyond poor. And that makes it
difficult for me to completely understand huge examples. And the smaller
examples I've managed to find don't work.

Since I want to get my application to do a few things in addition to reading
and writing the settings, I'd prefer to find a simple example and be able to
move on.

Has anyone out there cracked ConfigurationManager for a desktop app?

Thanks.
 
S

Smithers

I can't understand why Microsoft would provide surprisingly little guidance
on how to use the types in the System.Configuration namespace. It's been
around for a couple of years now and it's not nearly as straight-forward as
the MSDN documentation makes it seem at first glance. Having a few comments
with each type's members isn't helpful in this case. Jon Rista (author of
the code project articles below) should be given some award for his work
which compensates for MS falling flat on its face on this one.

The first of the following 3 articles is the most practical and helpful if
you want to understand how to make use of the new System.Configuration
types. The other articles offer additional insight (all by Jon Rista - some
guy who has spent a huge amount of time figuring it all out).

http://www.codeproject.com/dotnet/mysteriesofconfiguration.asp
http://www.codeproject.com/dotnet/mysteriesofconfiguration2.asp
http://www.codeproject.com/csharp/mysteriesofconfiguration3.asp


A couple of tips that might be useful:
1. googling this topic is especially USELESS because so much of what's out
there talks about the [now deprecated] ConfigurationSettings type (from 1.0
and 1.1). Whenever you see something that is based on ConfigurationSettings
you have to ignore it and keep looking.

2. The whole point of the new configuration management system (it appears to
me, anyway), is to provide us with strongly typed objects that maintain our
configuration settings. So rather than thinking of App.config or Web.config
as simply an XML layout for your configuration settings (it is that, too) -
think about App.config simply as a serialized version of your
application-specific configuration objects.

3. If point #2 is maddening ("geeze I just want to store and read a simple
custom collection of xml nodes"), then go ahead and either (1) use the new
stuff only for the built-in AppSettings and ConnectionStrings sections
(which are exposed natively); or (2) revert to the old school
ConfigurationSettings way of doing things.


-HTH
 
J

Jonathan Wood

Thanks Smithers for the detailed response. I've found most of the
descriptions for properties and methods in the .NET documentation are
pathetically unhelpful and make sense only when you already understand what
the property or method does.

The articles look fairly long and will take careful reading if I am to fully
understand everything they say. I've saved your post and will read them if I
have to. But I really wish someone would post a simple example--that would
be so easy for me. Perhaps others are having trouble with this as well.

Thanks again.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

Smithers said:
I can't understand why Microsoft would provide surprisingly little guidance
on how to use the types in the System.Configuration namespace. It's been
around for a couple of years now and it's not nearly as straight-forward as
the MSDN documentation makes it seem at first glance. Having a few comments
with each type's members isn't helpful in this case. Jon Rista (author of
the code project articles below) should be given some award for his work
which compensates for MS falling flat on its face on this one.

The first of the following 3 articles is the most practical and helpful if
you want to understand how to make use of the new System.Configuration
types. The other articles offer additional insight (all by Jon Rista -
some guy who has spent a huge amount of time figuring it all out).

http://www.codeproject.com/dotnet/mysteriesofconfiguration.asp
http://www.codeproject.com/dotnet/mysteriesofconfiguration2.asp
http://www.codeproject.com/csharp/mysteriesofconfiguration3.asp


A couple of tips that might be useful:
1. googling this topic is especially USELESS because so much of what's out
there talks about the [now deprecated] ConfigurationSettings type (from
1.0 and 1.1). Whenever you see something that is based on
ConfigurationSettings you have to ignore it and keep looking.

2. The whole point of the new configuration management system (it appears
to me, anyway), is to provide us with strongly typed objects that maintain
our configuration settings. So rather than thinking of App.config or
Web.config as simply an XML layout for your configuration settings (it is
that, too) - think about App.config simply as a serialized version of your
application-specific configuration objects.

3. If point #2 is maddening ("geeze I just want to store and read a simple
custom collection of xml nodes"), then go ahead and either (1) use the new
stuff only for the built-in AppSettings and ConnectionStrings sections
(which are exposed natively); or (2) revert to the old school
ConfigurationSettings way of doing things.


-HTH






Jonathan Wood said:
This is crazy. Does anyone have a simple example of reading a variable
from the application config file for a desktop application?

I've spent way too much time on this. I've found huge examples and lots
of help topics. But the .NET help topics are beyond poor. And that makes
it difficult for me to completely understand huge examples. And the
smaller examples I've managed to find don't work.

Since I want to get my application to do a few things in addition to
reading and writing the settings, I'd prefer to find a simple example and
be able to move on.

Has anyone out there cracked ConfigurationManager for a desktop app?

Thanks.
 
S

Smithers

Hi Jonathan:

By far the easiest thing for you to do is to retrieve (read-only) simple
name/palue pairs from App.config (or Web.config).

Here is a working sample (works with <appSettings> in App.config; slight
tweaking for Web.config):
/*******************************************************************/
// You must first set a project reference to System.Configuration.dll

// the following is the App.config file contents
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="customsetting1" value="Some text here"/>
<add key="customsetting2" value="Some other text here"/>
</appSettings>
</configuration>

//Here is the C# code that reads the above:
string theKey = string.Empty;
string theValue = string.Empty;
System.Configuration.Configuration appConfig =
System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
System.Configuration.KeyValueConfigurationElement customSetting =
appConfig.AppSettings.Settings["customsetting1"];
foreach (System.Configuration.KeyValueConfigurationElement currentElement in
appConfig.AppSettings.Settings)
{
theKey = currentElement.Key;
theValue = currentElement.Value;
}
/*******************************************************************/
The above technique would work for a <connectionStrings /> element:
ConnectionStrings and AppSettings are fully implemented for you by
System.Configuration types. You just use them "out of the box" (one
technique is that which I posted above; others are available).

Notes:
1. you cannot programmatically *write* to the <appSettings> or
<connectionString> elements.

2. If you want to programmatically write (in addition to reading), then you
have to go the more complex route presented in the links I gave earlier and
discussed below.

3. If you want your own custom configuration sections (beyond <appSettings>
and <connectionStrings>), then you have to go a far more complex route:

4. You will need a <configSections> element. It MUST MUST MUST be the very
first element within the opening <configuration> element. Everything will
choke if you have a <configSections> element that is, for example, located
below your <appSettings> element.
Don't forget this. You'll get the most vague "configuration system failed to
initialize" exception and NOTHING will work. Everything looks right - in
terms of syntax in both C# and App.config. But the whole freaking problem is
that your <configSections> section is just in the wrong *sequence* (not
depth) in App.config. That's just stupid. Anyway....

2. Suppose you need something even *slightly* more complex than a simple
name/value pairs available in <appSettings> and <connectionStrings>,
something like the following:

<MyCustomSection logExceptions="true" logProgress="true">
<WebSites>
<WebSite domainName="Site1.com" webServer="ServerName1" />
<WebSite domainName="Site2.com" webServer="ServerName1" />
<WebSite domainName="Site3.com" webServer="ServerName2" />
</WebSites>
</MyCustomSection>

If you want to programmatically read that, then you will need to create one
or more classes - yes write a bunch of code - to get your application to
recognize those sections.

In a nut shell, your classes EXTEND various System.Configuration types. At
the end of the effortwhat you have, and this is great, is a runtime object
that represents, from the example above, MyCustomSection. Your custom object
woudl have a strongly typed collection of WebSite objects and properties for
all of the attributes. Specifically, MyCustomSection would be your custom
type. It would have two boolean properties (one for each of the attributes:
logExceptions and logProgress); and a third property that exposes a strongly
typed collection of WebSite objects. Each WebSite object would, in turn,
have two string properties (one for each of the WebSite attributes,
domainName and webServer).

YES - this is a whole lot of work. But at the end of the day you have a
strongly typed collection of what-ever-it-is-that-you-want. The
System.Configuration types that you extend take care of all of the "heavy
lifting" of parsing the .config file as an XML document. You don't have to
worry about any of that. So that is the good news.

The bad news is that there is practically zero guidance on how to extend the
types in System.Configuration in a particular way so as to correctly work
with the custom XML structure you need or want.

So I'd suggest you do one of these:
1. Stay with the <appSettings> and <connectionStrings> sections - provided
that you can live with read-only name/value pairs.
2. If #1 is inadequate, then budget some time to go up the learning curve on
this unintuitive process of decyphering System.Configuration. The best
learning aid I've found are those articles I noted earlier.

Finally - I hope I'm wrong about all of the above and somehow failed to
locate some treasure trove of helpful documentation other than that which I
already pointed out. I doubt I've missed anything though - given the extent
of searching I undertook last week. Remember, practically all of the
"how-tos" and "recipes" for working with custom configuration data that
you'll find on the Web all work with the now depracated
ConfigurationSettings type. The few recipes for using the new
System.Configuration types offer practically zero perspective, and straying
from their sample XML structure results in nothing working.

HTH

- "Smithers"



Jonathan Wood said:
Thanks Smithers for the detailed response. I've found most of the
descriptions for properties and methods in the .NET documentation are
pathetically unhelpful and make sense only when you already understand
what the property or method does.

The articles look fairly long and will take careful reading if I am to
fully understand everything they say. I've saved your post and will read
them if I have to. But I really wish someone would post a simple
example--that would be so easy for me. Perhaps others are having trouble
with this as well.

Thanks again.

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

Smithers said:
I can't understand why Microsoft would provide surprisingly little
guidance on how to use the types in the System.Configuration namespace.
It's been around for a couple of years now and it's not nearly as
straight-forward as the MSDN documentation makes it seem at first glance.
Having a few comments with each type's members isn't helpful in this case.
Jon Rista (author of the code project articles below) should be given some
award for his work which compensates for MS falling flat on its face on
this one.

The first of the following 3 articles is the most practical and helpful
if you want to understand how to make use of the new System.Configuration
types. The other articles offer additional insight (all by Jon Rista -
some guy who has spent a huge amount of time figuring it all out).

http://www.codeproject.com/dotnet/mysteriesofconfiguration.asp
http://www.codeproject.com/dotnet/mysteriesofconfiguration2.asp
http://www.codeproject.com/csharp/mysteriesofconfiguration3.asp


A couple of tips that might be useful:
1. googling this topic is especially USELESS because so much of what's
out there talks about the [now deprecated] ConfigurationSettings type
(from 1.0 and 1.1). Whenever you see something that is based on
ConfigurationSettings you have to ignore it and keep looking.

2. The whole point of the new configuration management system (it appears
to me, anyway), is to provide us with strongly typed objects that
maintain our configuration settings. So rather than thinking of
App.config or Web.config as simply an XML layout for your configuration
settings (it is that, too) - think about App.config simply as a
serialized version of your application-specific configuration objects.

3. If point #2 is maddening ("geeze I just want to store and read a
simple custom collection of xml nodes"), then go ahead and either (1) use
the new stuff only for the built-in AppSettings and ConnectionStrings
sections (which are exposed natively); or (2) revert to the old school
ConfigurationSettings way of doing things.


-HTH






Jonathan Wood said:
This is crazy. Does anyone have a simple example of reading a variable
from the application config file for a desktop application?

I've spent way too much time on this. I've found huge examples and lots
of help topics. But the .NET help topics are beyond poor. And that makes
it difficult for me to completely understand huge examples. And the
smaller examples I've managed to find don't work.

Since I want to get my application to do a few things in addition to
reading and writing the settings, I'd prefer to find a simple example
and be able to move on.

Has anyone out there cracked ConfigurationManager for a desktop app?

Thanks.
 
J

Jonathan Wood

Smithers,
2. If you want to programmatically write (in addition to reading), then
you have to go the more complex route presented in the links I gave
earlier and discussed below.

Which I guess I'll have to do. The whole thing will be pointless for me if I
can't save my settings.

For the languages I've been using previously (VC++ and VB6), this thing is
so simple to do. Under .NET, it takes an enourmous 3-part article to
explain. I mean, if save and restore the settings was all my app needed to
do, that wouldn't be that big a deal. But if many elements of the app are
this messy, sheesh!

I'm trying to like .NET--really! But in so many ways, it really sucks.
YES - this is a whole lot of work. But at the end of the day you have a
strongly typed collection of what-ever-it-is-that-you-want. The
System.Configuration types that you extend take care of all of the "heavy
lifting" of parsing the .config file as an XML document. You don't have to
worry about any of that. So that is the good news.

Ack! I wonder how long System.Configuration will be maintained for
compatibility. It sounds more reasonable.

Thanks for the response.

Jonathan
 
S

Smithers

Morning Jonathan,

RE:
<< For the languages I've been using previously (VC++ and VB6), this thing
is so simple to do. >>
and
<< Under .NET, it takes an enourmous 3-part article to explain. I mean, if
save and restore the settings was all my app needed to do, that wouldn't be
that big a deal. But if many elements of the app are this messy, sheesh! >>
My experience with VB6 (which is extensive) is that it makes easy things
very easy and hard things very hard. Reading and writing to a text file
would certainly be in the "easy" category. But to be accurate about this
particular situation (reading App.config), we aren't just reading and
writing to a text file. We're reading/writing to an XML file that has some
specific syntax requirements (per my previous post). Not that I'm going to
defend the unintuitive System.Configuration types and its woefully
inadequate documentation. Just wanting to put this in perspective. With VB6,
to accomplish the same, you'd have to parse the .config file as an XML
document, then access various elements via the DOM. You'd then have to
translate the DOM into your custom types in order to get a strong-typed
representation of your application's configuration. That's more individual
steps than with the .NET way (although probably more intuitive and easier to
do than decypher System.Configuration!).

Alternatively, you could come up with a text file that doesn't have an XML
structure and just parse it using basic string reading/writing
functionality. This would be substantially easier than any other
alternative - although the self-documenting nature of XML would be out the
window.

RE:
<< I'm trying to like .NET--really! But in so many ways, it really sucks.>>

I don't think that any language or platform will ever surpass the
intuitiveness of VB6. They may rival it, but not surpass it by much. But
along the lines I stated above about VB6 making easy things very easy and
hard things very hard: you can see .NET as making easy things
not-quite-so-easy and hard things relatively easy to do. So the learning
curve with .NET starts out at a higher point than the curve of VB6, but it
isn't nearly as steep when it comes time to do the more difficult things.
That's just the nature of this beast.

Things that were easy in VB6 can seem rediculously difficult to do in .NET.
But you get far more mileage out of your learning efforts with .NET. For
example, if all you want to do is read and write to a simple text file...
that takes an inordinate amount of work in .NET (compared to VB6) because
the System.IO types have confusing names and an unintuitive object hierarchy
(this fact is stated on pages 17 and 18 in the book Framework Design
Guidelines). This is in part because in .NET a file is treated simply as a
"stream" abstraction (a sequence of bytes; which in the case of a file
happens to be persisted to disk). But once you "get it" and can work with
files (streams) on disk, then it is a relatively TRIVIAL effort to
generalize that knowledge to reading and writing across the wire - even
encrypting your communications. This is because .NET provides streams for
just about any sequence of bytes you could possibly want to read and write
(memory streams, network streams, encrypted network streams, etc). So once
you finish the comparatively steep learning curve in .NET on how to write to
a text file using streams in .NET - you are just a very short curve away
from sending an encrypted comunication across a network. In VB6, *nothing*
about reading and writing a file can be generalized to working with sockets
and sending encrypted communications across the wire. So that's the draw of
..NET.

-HTH

-"Smithers"
 
J

Jonathan Wood

Smithers,
My experience with VB6 (which is extensive) is that it makes easy things
very easy and hard things very hard. Reading and writing to a text file
would certainly be in the "easy" category. But to be accurate about this
particular situation (reading App.config), we aren't just reading and
writing to a text file. We're reading/writing to an XML file that has some
specific syntax requirements (per my previous post).

Yeah, I made a pretty good living showing people how to do the hard things
in VB6 (in VBPJ articles and columns, et. al). This does make me think of
one thing, however: maybe it would be easier just to read and write a test
file using my own settings class. After all, what do I care if it is stored
in XML format or not? I gain nothing from the added overheads and
complexity.
Alternatively, you could come up with a text file that doesn't have an XML
structure and just parse it using basic string reading/writing
functionality. This would be substantially easier than any other
alternative - although the self-documenting nature of XML would be out the
window.

Exactly. Something definitely worth considering.
RE:
<< I'm trying to like .NET--really! But in so many ways, it really
sucks.>>

I don't think that any language or platform will ever surpass the
intuitiveness of VB6.

We'll have to see about "any language", but your point is taken. What gets
me is that C++ and MFC seem WAY more intuitive to me. Certainly, a
description of how to read and write app settings in an MFC app would take a
tiny paragrah. And VC++'s reputation is that it's hard.

I acknowledge that .NET has some powerful features. For example, I was able
to write a simple application that loads and resizes a graphic image with
excellent quality. That's cool. And, ultimately, it is Web development that
interests me. But the lack of replies to this thread (besides yourself)
illustrates to me that there are probably a lot of people out there using
..NET who are having trouble with some of the complexities and poor
documentation.
Things that were easy in VB6 can seem rediculously difficult to do in
.NET. But you get far more mileage out of your learning efforts with .NET.
For example, if all you want to do is read and write to a simple text
file... that takes an inordinate amount of work in .NET (compared to VB6)
because the System.IO types have confusing names and an unintuitive object
hierarchy (this fact is stated on pages 17 and 18 in the book Framework
Design Guidelines). This is in part because in .NET a file is treated
simply as a "stream" abstraction (a sequence of bytes; which in the case
of a file happens to be persisted to disk). But once you "get it" and can
work with files (streams) on disk, then it is a relatively TRIVIAL effort
to generalize that knowledge to reading and writing across the wire - even
encrypting your communications. This is because .NET provides streams for
just about any sequence of bytes you could possibly want to read and write
(memory streams, network streams, encrypted network streams, etc). So once
you finish the comparatively steep learning curve in .NET on how to write
to a text file using streams in .NET - you are just a very short curve
away from sending an encrypted comunication across a network. In VB6,
*nothing* about reading and writing a file can be generalized to working
with sockets and sending encrypted communications across the wire. So
that's the draw of .NET.

Yes, I get all that. In the end, I guess it doesn't matter much. I'm a
developer and I need to be competent developing on the latest platform. I
realize there will be some significant benefits for me once I've mastered
..NET. But I don't have to like it. ;-)

Thanks.
 
G

G.Doten

Smithers said:
2. If you want to programmatically write (in addition to reading), then you
have to go the more complex route presented in the links I gave earlier and
discussed below.

If you use Visual Studio 2005 you can just right-click on a project's
Properties node and select Open. Then go to the Settings tab. Just type
in you new setting's name and a default value. If you make the setting
application-copied then it cannot be written to; if you make the setting
user-scoped it can be written to easily.

VS will generate a Settings.cs file with a Settings class in it. To use
this just do this:

using <your-namespace>.Properties;

int maxLoops = Settings.Default.MaxLoops;

// You can now use maxLoops as you would like.

Settings.Default.MaxLoops = 154;
Settings.Default.Save();

// You've just changed the MaxLoops setting to be 154.

This doesn't read and/or write to the <appSettings> section but is great
for adding user- or application-specific settings right in your class
library and/or application. But these VS-supported settings are wicked
simple to use and very flexible (say you're working on a class library,
the settings for that library can easily be copied to an app.config for
tailoring by code that uses the class library).

I decided to go through the pain of converting all my .NET 1.1 and prior
based ConfigurationSettings stuff to this new technique because the new
stuff didn't seem to be worth figuring out giving the VS built-in
support for the new settings. If MS does a wholesale change of the
"settings architecture" again I'm sticking with this one introduced in
..NET 2.0 - [obsolete] or not!
 
S

Smithers

Thanks for pointing out something I had missed.

The Settings.cs and related VS functionality of which you speak: is it
limited to name/value pairs - or can we also store collections of related
stuff?

-"Smithers"






G.Doten said:
Smithers said:
2. If you want to programmatically write (in addition to reading), then
you have to go the more complex route presented in the links I gave
earlier and discussed below.

If you use Visual Studio 2005 you can just right-click on a project's
Properties node and select Open. Then go to the Settings tab. Just type in
you new setting's name and a default value. If you make the setting
application-copied then it cannot be written to; if you make the setting
user-scoped it can be written to easily.

VS will generate a Settings.cs file with a Settings class in it. To use
this just do this:

using <your-namespace>.Properties;

int maxLoops = Settings.Default.MaxLoops;

// You can now use maxLoops as you would like.

Settings.Default.MaxLoops = 154;
Settings.Default.Save();

// You've just changed the MaxLoops setting to be 154.

This doesn't read and/or write to the <appSettings> section but is great
for adding user- or application-specific settings right in your class
library and/or application. But these VS-supported settings are wicked
simple to use and very flexible (say you're working on a class library,
the settings for that library can easily be copied to an app.config for
tailoring by code that uses the class library).

I decided to go through the pain of converting all my .NET 1.1 and prior
based ConfigurationSettings stuff to this new technique because the new
stuff didn't seem to be worth figuring out giving the VS built-in support
for the new settings. If MS does a wholesale change of the "settings
architecture" again I'm sticking with this one introduced in .NET 2.0 -
[obsolete] or not!
 
G

G.Doten

Smithers said:
The Settings.cs and related VS functionality of which you speak: is it
limited to name/value pairs - or can we also store collections of related
stuff?

You can store almost any type you want. Look in Visual Studios' Settings
tab and you'll see a type drop-down for the setting. Set it to whatever
you want. You can even browse to one of your own types.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top