C# DLL config file

It is not trivial to create a .NET configuration file for a .DLL, and for good reason. The .NET configuration mechanism has a lot of features built into it to facilitate easy upgrading/updating of the app, and to protect installed apps from trampling each others configuration files.

There is a big difference between how a DLL is used and how an application is used. You are unlikely to have multiple copies of an application installed on the same machine for the same user. But you may very well have 100 different apps or libraries all making use of some .NET DLL.

Whereas there is rarely a need to track settings separately for different copies of an app within one user profile, it’s very unlikely that you would want all of the different usages of a DLL to share configuration with each other. For this reason, when you retrieve a Configuration object using the “normal” method, the object you get back is tied to the configuration of the App Domain you are executing in, rather than the particular assembly.

The App Domain is bound to the root assembly which loaded the assembly which your code is actually in. In most cases this will be the assembly of your main .EXE, which is what loaded up the .DLL. It is possible to spin up other app domains within an application, but you must explicitly provide information on what the root assembly of that app domain is.

Because of all this, the procedure for creating a library-specific config file is not so convenient. It is the same process you would use for creating an arbitrary portable config file not tied to any particular assembly, but for which you want to make use of .NET’s XML schema, config section and config element mechanisms, etc. This entails creating an ExeConfigurationFileMap object, loading in the data to identify where the config file will be stored, and then calling ConfigurationManager.OpenMappedExeConfiguration to open it up into a new Configuration instance. This will cut you off from the version protection offered by the automatic path generation mechanism.

Statistically speaking, you’re probably using this library in an in-house setting, and it’s unlikely you’ll have multiple apps making use of it within any one machine/user. But if not, there is something you should keep in mind. If you use a single global config file for your DLL, regardless of the app that is referencing it, you need to worry about access conflicts. If two apps referencing your library happen to be running at the same time, each with their own Configuration object open, then when one saves changes, it will cause an exception next time you try to retrieve or save data in the other app.

The safest and simplest way of getting around this is to require that the assembly which is loading your DLL also provide some information about itself, or to detect it by examining the App Domain of the referencing assembly. Use this to create some sort of folder structure for keeping separate user config files for each app referencing your DLL.

If you are certain you want to have global settings for your DLL no matter where it is referenced, you’ll need to determine your location for it rather than .NET figuring out an appropriate one automatically. You’ll also need to be aggressive about managing access to the file. You’ll need to cache as much as possible, keeping the Configuration instance around ONLY as long as it takes to load or to save, opening immediately before and disposing immediately after. And finally, you’ll need a lock mechanism to protect the file while it’s being edited by one of the apps that use the library.

Leave a Comment