The beauty of blogs, in particular this one: I can flaunt my ignorance on any given area. A few nights ago I thought I'd update my current development project to have its connection string maintained in a config file so that it could be changed without a recompile in a single location.
I knew this was the approach we'd eventually take having used it like breathing on all of my previous .NET projects (which were ASP.NET). But Windows Forms applications are slightly different and I ran into the brick wall of not grokking the structure Microsoft uses for configuration.
The big problem in my understanding was that I wanted to have my configuration read in a separate library, thinking I'd reuse the pattern on any future project where I wanted to do something similar. So I created a library project and knowing a little but not enough created a config file manually to use. Knowing a little but not enough (or not updated?) I named my configuration file ConfigHelper.dll.config because this is a well known convention in .NET. I also manually copied this file to the \bin folder and even considered adding a "post build event" to the Visual Studio 2005 project to do this. And when it didn't work and my attempts to read the config file weren't successful, I became very frustrated and even took the time to write it up. Luckily no one besides A the jedi master reads this blog so my voice of ignorance got drown in the black hole that is blogger. No matter: this blog is for me, like a "captains log" to chart my experiences and thoughts.
I realized a while back that I knew just enough from the past few years programming ASP.NET to make ignorant mistakes and convoluted work-around solutions so I've been reading Brian Noyes's Data Binding with Windows Forms 2.0 on Safari trying to grok the whole picture as Microsoft intends it.
So here is the skinny, as embarrasing as it is for me to explain how wrong I had it:
1. In your project, create an App.config file. In Visual Studio 2005 this is the "Application Configuration File" option.
2. Make entries as you like in the configuration file.
3. Compiling your application will produce a MyAssembly.exe.config or MyLibrary.dll.config file in the \bin directory.
4. Libraries aren't meant to read from their own configuration files. Hence attempting to read an entry even if you've manually copied over your MyLibrary.dll.config file will result in an empty string once retrieved. BUT!
5. BUT! BUT! The library is designed to read values from the configuration file of the executable. So if you place the following line in your library:
string foo = ConfigurationManager.AppSettings["bar"];
Your library is looking for the "bar" value in the configuration file of your application.
To my own credit, a lot of the time when I find myself fighting with something I usually know deep down that it's a struggle to understand what the framework designer intended and not something that is "stupid." In this case, what the framework designers intended is quite elegant because when you have, like us, many different libraries that all need to pull something common (connection string is probably most obvious) it can be based on the configuration of the application and managed in a single location.
Okay, now that I got the memo, I can move on.