.NET 3.5 DLL using its own config file

2019-01-18 14:38发布

问题:

I need to have a .NET 3.5 DLL have its own config file. This DLL could be called from many different apps so the information (like connection strings) stored in the config file needed to be kept in a config file that the DLL can reference. What I want is when the DLL is used, I need to "switch" the config file that is used to reference information to be the DLLs config file. Then when the DLL is done with using the configuration information, the switch is made back to the default one. The DLL is written using .NET 3.5. I have been searching for how to do this and what I keep finding is how to merge information with an exe's app.config file. In my case, I don't know how where this DLL will be used to modify any exe's app.config files out there. This solution needs to be stand alone. However, my base classes used to create the DLL (which contain business objects) are expecting to lookup the connection string and other information in a config file so that is why I need to "switch" to my DLL config file at the time when it is accessed and then switch it back so I don't mess up the exe app that called the DLL.

回答1:

The .NET 2.0 and up configuration system gives you capabilities - you can e.g. load a specific config file on demand. It's a bit more work - but it works.

You'd have to do something like this:

// set up a exe configuration map - specify the file name of the DLL's config file
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = "ConfigLibrary.config";

// now grab the configuration from the ConfigManager
Configuration cfg = ConfigurationManager
                   .OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);

// now grab the section you're interested in from the opened config - 
// as a sample, I'm grabbing the <appSettings> section
AppSettingsSection section = (cfg.GetSection("appSettings") as AppSettingsSection);

// check for null to be safe, and then get settings from the section
if(section != null)
{
   string value = section.Settings["Test"].Value;
}

You also need to make sure that the config for the class library DLL is being built and copied to a location where you can get at it. Worst case you need to specify a specific config file and make sure it gets copied to the output directory by setting its "Copy To Output Directory" property in the Visual Studio properties window.

You should also check out Jon Rista's three-part series on .NET 2.0 configuration up on CodeProject.

  • Unraveling the mysteries of .NET 2.0 configuration
  • Decoding the mysteries of .NET 2.0 configuration
  • Cracking the mysteries of .NET 2.0 configuration

Highly recommended, well written and extremely helpful!

Marc



回答2:

Generally when you have settings at the application level, you need to generate those settings at the application level, and then percolate them through your libraries. It adds a few more lines of code to your initialization to inject dependencies, but you are essentially trying to do that anyway.

You are going to run into way more problems than its worth if you try to include a config file for just the dll side by side with every deployment of your library, and it just doesn't make a lot of sense semantically.

Take System.Data for example...when you create a connection, you specify the connection string, not create a separate config file for just the connection string to deploy side by side with the System.Data library. [and that would cause tons of problems since it likely resides in the GAC on your system anyway]



回答3:

You cannot use the built-in .Net configuration system to do this. It is designed (as it should be ) to configure application processes, not indvidual Dlls. The correct way to go about this is to add the configuration settings for the dll into the app.config system for each executable application that "uses" (has a reference to) that dll. (or in the machine.config)

  • Simply making the settings accessible to ALL applictions that uset he dll can be accomplished by putting them in the Machine.config (in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG for .Net2.0

If you don't want to do it that way, then you will have to write your own code to open, read, and write frm a custom Xml file, (or whatever format you choose to use) to extyract those settings.



回答4:

The easiest answer to this would be to put the values in the machine.config. That way all apps using the dll will be able to access the information through the .net app configuration classes. With this way too, if you absolutely need to override a value for a certain applicatin, you can override it in the main application's app.config file.



回答5:

I know this post is a little old, but I wanted to throw my 2 cents in. While in may cases, I would agree that the application should supply the settings, not the dll. I have found one situation in while dll specific configs seems to be more desireable.

We use the scheduling/task applicaiton Quartz.NET. We developed a interface to create and monitor jobs against the Quartz server. One of the great things about Quartz.NET is that you create your "job" programs and compile them into DLLs and then just drop them in the Quartz.NET server folder and through reflection and such, Quartz is able to start using the new DLL without any additional tweaks to Quartz server...if there is no information that needs to be held in config files.

With Quartz server if you have any specific config information that should be kept in a config file, you have to put it in the Quartz.NET config file. We have created several "job" applications, each with their own bits of config information, so now our Quartz.NET config file is littered with all these unrelated settings. Having a dll specific config file would greatly reduce the clutter of the Quartz.NET server. The only other option I see is to add all these individual settings into a settings DB table, but for consolidating and maintenance of the code, for our purposes, individual config files are preferable.

Just throwing that out there to think about.