Introduction
This article describes how to read information from a config file exactly like the app.config file, including information on linking in external files, using custom configuration section handlers, sections, and section groups.
Background
I have looked at several articles that build everything from preference sections to simply building something that reads a section from XML that looks like the appSettings. What I really needed was a way to move settings into and out of the app.config file. I needed it to do two very specific things that none of the others did. First, I needed it to use custom configuration section handlers, and second, I needed it to assume the file name based on the assembly name because I didn't want to have to track the names of files.
Using the code
The code is used just like the System.ConfigurationSettings class in .NET, just from a different namespace.
string val =
CustomConfigurationSettings.ConfigurationSettings.AppSettings["myTestKey"];
This is the simplest way to use it. Using it this way assumes a config file named assemblyname.dll.config or executable.exe.config, really it just picks up the output file name for the assembly and adds .config to it. The file should be in the same directory as the assembly. It supports all the built-in classes in .NET that support the IConfigurationSectionHandler interface and uses them to read all sections of the config file. It also supports using external files for appSettings just like the app.config does.
<appSettings file="filename.config">
<add key="test" value="myTest"/>
</appSettings>
If you don't want to use the appSettings section, or you want to use a different file name then the one that is assumed, it works just like the System.ConfigurationSettings class, except that the ConfigurationSettings.GetConfig is overloaded to support passing a file name that can be whatever you want as long as the format of the file matches the app.config.
NameValueCollection values = (NameValueCollection)
CustomConfigurationSettings.ConfigurationSettings.GetConfig("myconfigSection",
"myConfig.config");
string val = values["myTestKey"];
Points of Interest
Loading the external file for the AppSettings looked like it was going to be easy, just use the NameValueFileSectionHandler and that should do it, right? Well, not so fast! It didn't work. It was always returning null. I looked at what it was doing internally using Reflector and it looked pretty simple, but it was using a class marked as internal so I couldn't use that to reproduce the code. It wasn't that hard to just get the file name and load it myself, and then use the same logic that I was using on the first file, then set the parent context for the NameValueSectionHandler which combines the two sets of information into the section handler.
|
|
 |
 | appConfig file nageshn27@gmail.com | 4:06 19 Jun '08 |
|
 |
How do I write the '"' & '<' symbols in AppConfig file
|
|
|
|
 |
 | app.config problem monu_khan | 10:55 27 May '08 |
|
 |
how to add System.Machine name Value Here
<add key="con" value="server=Enviornment.Machinename\INFOSOFT\ist;database=sm;user id=sa;pwd=****" />
|
|
|
|
 |
 | How can it work within web service or asp.net application? colacat | 20:32 31 May '06 |
|
 |
Hello ONeil ^__^
This is nice article for owning class configure file. I tried your deom project, they did well in your ConfigTestApp project. Now I try to add the ConfigurationSettings.cs into class(class A) and compile the class A, then in the Web Service Application(WebProject B) add reference for Class A(A.dll). Copy the configure file (A.dll.config) to the WebProject bin directory(WebProject b\bin). The result was fail!(HTTP 500 erros),the error stack as below Do you know how to use the Custom app.config correct in Web Application ?
[InvalidOperationException: 無法辨認的要求格式(in Chinese)。] System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +388 System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +94 System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, String path, String pathTranslated, Boolean useAppConfig) +699 System.Web.MapHandlerExecutionStep.System.Web.HttpApplication+IExecutionStep.Execute() +95 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Many thanks.
Louis
|
|
|
|
 |
 | CallingAssembly file name for default config file is confusing. Michael Freidgeim | 16:33 15 Nov '05 |
|
 |
I found that your static method AppSettings reads different files (dllname.dll.config or executable.exe.config) depending from which assembly it is called in the same application. I think that if no file is specified, the property AppSettings and method GetConfig(string sectionName) should open executable.exe.config regardless where it is called from. I beleive that it is how MS System.Configuration.ConfigurationSettings works. So instead of instead of using Assembly.GetCallingAssembly() your methods should call Assembly.GetEntryAssembly() or Application.ExecutablePath. E.g.
Debug.Assert(StringType.StrCmp(Assembly.GetEntryAssembly().Location, Application.ExecutablePath, false) == 0); string sConfigFileName = Application.ExecutablePath + ".config";
Michael Freidgeim. Blog: http://geekswithblogs.net/mnf/
|
|
|
|
 |
|
 |
I needed to have different config files for each assembly, so it does make sense that it would get different file names when calling from different assemblies. I agree that there is a better solution then JUST calling assembly. I have been working on a change that would allow you to add an assembly attribute that would allow you specify a mapping for a key in the app.config to be able to specify what file an assembly or a group of assemblies would use or to allow you specify the config file that you wanted for your assembly.
I will post the updates here when they are ready. This would clear up a little of what you described.
|
|
|
|
 |
 | Minor suggesions for overload with file name. Michael Freidgeim | 19:51 3 Apr '05 |
|
 |
Thanks for the article. It's useful. It will be good in the GetConfig(string sectionName, string configFileName) overload to handle null or empty configFileName to fill it with GetCallingAssembly. I've also modified ExternalFileTest to actually test external file
public void ExternalFileTest() { NameValueCollection values = (NameValueCollection)ConfigurationSettings.GetConfig("appSettings","Development.config"); string val = values["ApplicationName"]; Assert.AreEqual(val, "Configuration Tests", "Incorrect Value found"); }
Michael
|
|
|
|
 |
|
 |
Thanks for the feedback, I am glad that you found it useful. I didn't mean to include those Unit Tests, I will update them to my current ones. They were not complete.
As, for the GetConfig overload, I am going to add a null check to it, but I am going to throw a ArgumentNullException. I don't want to make an assumption that if someone passes null or empty that they want the other config. What if they have the same key with a different value in a config that matches the assembly name. This can (and probably will) cause someone to think that they are reading from the other file and it will make it difficult to figure out what is going on.
If you want the default file name, then call the other overload, or build the default name and pass it in.
Thanks again for the feedback and I will get this updated in the next day or two.
-Brian O'Neil
|
|
|
|
 |
|
|