Configuration settings for .NET class libraries (DLLs)
It is fairly easy to specify configuration settings for .NET executables, by adding an app.config file to the project, that is built into a .exe.config file in the executable folder. However, since libraries or DLLs do not run on their own, and rely on clients to execute, how does one specify different settings in different calling environments, especially if the library files are placed in a single location on the computer such as the global assembly cache?
Recently this question arose so many times in the projects that I have been working on that I decided to investigate the options more closely. I found that some subtleties of the approaches have not been explained anywhere, so decided to summarize the available options here. There appear to be four different ways to specify library settings, each with its own benefits and failings.
1. The settings can be created in the class library by adding them to the ‘appSettings’ element of the app.config added to the library project (see figure).
This is a very simple way of specifying settings, and can be accessed in the library code as shown below:
The drawback of this method is that every calling assembly has to duplicate this setting in its own app.config (compiled into a .exe.config or .dll.config), since that is the only place searched by the code above. The situation becomes cumbersome when the number of settings required by the library increases.
2. The settings can be created in the class library as custom settings, by adding a settings file to the project (http://msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx), and specifying the settings to be used in the Settings designer of Visual Studio (see below),
or by manually entering them in the custom section of app.config as shown below:
Visual Studio conveniently generates a class to access the settings (see below):
The settings can be accessed in the library code as follows:
Once again, if the setting is to be provided by the calling assembly, it has to be included as a custom setting in the exact same format in the calling assembly’s .exe.config. This is fairly cumbersome as the number of settings increases. However, an advantage (or disadvantage) of this method is that the default value of the setting is compiled into the library code via the ‘DefaultSettingValueAttribute’ in the Visual Studio generated code (see above). Hence, if the calling assembly does not provide the setting, the default value is used. This appears desirable only in a test context, as in production code, the user has no way of knowing the default setting that was applied in the library unless explicitly specified in a document or config file supplied with the library files.
3. A third way to provide the configuration settings for a library, is again via the ‘appSettings’ section of app.config, compiled into the library .dll.config. The difference here is that the library code used to retrieve the settings is as follows:
This code looks for the settings in the library .dll.config placed in the same folder as the library .dll. The advantage of this method is that the configuration settings need not be copied into the calling assembly’s app.config. It is sufficient to place the library’s .dll.config file provided with the library, in the same location as the library .dll file. The disadvantage is that the library files cannot be placed in a central location (if different settings are to be applied) or in the global assembly cache (GAC) to be used by several calling assemblies.
4. A fourth way to provide the settings is to define them in a custom configuration file of any name, and retrieve them using the code shown below:
This code looks for the settings in the ‘appSettings’ element of the file called ‘custom.config’ in the calling assembly’s executable folder. The advantage here is that the library .dll can be placed in a central location or the GAC, and still use different settings based on the values specified in ‘custom.config’ placed in each calling assembly’s executable folder. Further, the settings do not need to be duplicated in the calling assembly’s own .exe.config or .dll.config.