Click here to Skip to main content
15,892,005 members
Articles / Programming Languages / C#
Article

App.Config for your DLL

Rate me:
Please Sign up or sign in to vote.
3.56/5 (17 votes)
11 Nov 2005Public Domain3 min read 288.9K   50   37
Using an app.config in your DLL.

Introduction

When developing DLLs for distribution, it is often desired to have an app.config file associated with that DLL. However, the .NET 1.1 Framework only allows a single app.config and it is usually associated with the running application. This really leaves developers in a pinch as they do not know if an application is using an app.config to "merge" its entries into, or they require the application developer to include entries into their config file for DLL usage.

Background

One method commonly used is to write your own XML file and put your configuration info there. This method has several drawbacks. What if you have included a third party DLL that has configuration information that it expects to see in an app.config file? You are now stuck with the same problem. One such case of this problem arises when you use the Microsoft Enterprise Library in your DLL. The Libraries configuration tool adds a line into the app.config file that points to its own config file for internal use. When you call a library class, it looks in the app.config file for the name of its own config file. Things get ugly from here.

If you have attempted to Google an answer to this problem, you will find "can't be done". This article will explain how it can be done.

I want to start by stating the following disclaimer(s): It is not a normal practice to use reflection to "patch" back another class. This example is an extreme case to get around what I consider is a serious flaw in the .NET Framework. Portability was not a factor when developing this technique. This technique is not needed with .NET 2.0 in my understanding. All that said, let's get started.

Using the code

The .NET Framework reads the application configuration file into a static hashtable whenever the application domain is first referenced. Once it is read, it cannot be reread or modified. This is unfortunate as it does not allow us to call any methods or properties to alter this behavior. Not accepting that there is no workaround, I started to snoop into the .NET Framework System.Dll file using Lutz Roeder's .NET Reflector. What I found is that you can make the framework reread the config file if you reset its internal variables into thinking that the app.config file has not been read. Doing this is ugly, but desperate people take desperate measures.

The following code is a simple class to demonstrate how to do this. I will leave it up to the reader to put this in your own code.

The main point of all this is to change the ConfigurationSettings class static variable "_configurationInitialized" to false, and null out the "_configSystem". Doing so will make the framework read the app.config file into memory. It is very important to undo the changes made before you leave. If not, the using application will now be pointing at your DLL's config file. One method to ensure this safety is to wrap your config parameters into a class. I have added a static ConnectionString method to this class for demonstration purposes. It uses the C# "using" statement to make sure that our object is destroyed, and that "Dispose" is called to undo our changes. You can wrap calls to the Enterprise Library, or another third party DLL the same way.

C#
internal class MyDllConfig : IDisposable
{
    private string _oldConfig;
    private bool _libCompat;
    private const string _newConfig = "mydll.dll.config";
    // don't forget to rename this!!

    internal MyDllConfig()
    {
        _libCompat = Assembly.GetAssembly(typeof(
          ConfigurationSettings)).GetName().Version.ToString().
          CompareTo("1.0.5000.0") == 0;
        _oldConfig = AppDomain.CurrentDomain.GetData(
               "APP_CONFIG_FILE").ToString();
        Switch(_newConfig);
    }
    protected void Switch(string config)
    {    
        if ( _libCompat )
        {
            AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE",config);
            FieldInfo fiInit = typeof(
                System.Configuration.ConfigurationSettings).GetField(
                    "_configurationInitialized",
                    BindingFlags.NonPublic|BindingFlags.Static);
            FieldInfo fiSystem = typeof(
                System.Configuration.ConfigurationSettings).GetField(
                    "_configSystem",BindingFlags.NonPublic|BindingFlags.Static);
            if ( fiInit != null && fiSystem != null )
            {
                fiInit.SetValue(null,false);
                fiSystem.SetValue(null,null);
            }
        }
    }

    public void Dispose()
    {
        Switch(_oldConfig);
    }

    public static string ConnectionString()
    {
        string cstr;
        using ( new MyDllConfig() )
        {
            cstr = ConfigurationSettings.AppSettings["ConnectionString"];
        }
        return cstr;
    }
}

Points of Interest

I have place a small sanity check into this class that checks the version number of the System DLL that this was written for. If another version is detected, this patch is bypassed.

The AppDomain has a property SetupInformation that has a ConfigurationFile property. I found that if you set your app's config file name using this property then it is ignored. Using the SetData method causes the class to re-initialize this variable and gives us our desired results, including adding the application path onto our filename for us!

The Visual Studio IDE will allow you to place a generic app.config file into your DLL project. Adding the following line to your post build events will copy and rename this file to the appropriate place.

Copy $(ProjectDir)app.config $(TargetPath).config

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Web Developer
United States United States
Been involved in computer hardware and software since 1977. Experience includes Windows, Unix and embedded realtime systems. I own a software development company and have been CTO and Lead Engineer for both small and large companies.

Comments and Discussions

 
GeneralFramework .NET 2.0 Pin
Carloni21-Feb-06 7:54
Carloni21-Feb-06 7:54 
GeneralRe: Framework .NET 2.0 Pin
n10sive21-Feb-06 9:34
n10sive21-Feb-06 9:34 
NewsRe: Framework .NET 2.0 Pin
Mazhekin7-May-06 4:35
Mazhekin7-May-06 4:35 
GeneralRe: Framework .NET 2.0 Pin
Jeff_1_2_319-Mar-07 13:35
Jeff_1_2_319-Mar-07 13:35 
QuestionSetupInformation Pin
Karthik Krishnaswami16-Jan-06 18:11
Karthik Krishnaswami16-Jan-06 18:11 
AnswerRe: SetupInformation Pin
n10sive16-Jan-06 18:39
n10sive16-Jan-06 18:39 
GeneralRe: SetupInformation Pin
Karthik Krishnaswami16-Jan-06 19:24
Karthik Krishnaswami16-Jan-06 19:24 
AnswerRe: SetupInformation Pin
Kerem Kat6-Jan-11 1:56
Kerem Kat6-Jan-11 1:56 
MSDN says:
Changing the properties of an AppDomainSetup instance does not affect any existing AppDomain. It can affect only the creation of a new AppDomain, when the CreateDomain method is called with the AppDomainSetup instance as a parameter.
GeneralHmm Pin
desertfoxmb29-Nov-05 7:30
desertfoxmb29-Nov-05 7:30 
GeneralRe: Hmm Pin
desertfoxmb29-Nov-05 7:35
desertfoxmb29-Nov-05 7:35 
GeneralRe: Hmm Pin
n10sive29-Nov-05 7:46
n10sive29-Nov-05 7:46 
GeneralRe: Hmm Pin
desertfoxmb29-Nov-05 8:14
desertfoxmb29-Nov-05 8:14 
GeneralLoading DLL in another AppDomain Pin
José Joye16-Nov-05 10:25
José Joye16-Nov-05 10:25 
GeneralCheck out custom app.config here: http://www.codeproject.com/csharp/CustomConfig.asp Pin
gigatoad15-Nov-05 6:48
gigatoad15-Nov-05 6:48 
GeneralRe: Check out custom app.config here: http://www.codeproject.com/csharp/CustomConfig.asp Pin
n10sive15-Nov-05 7:21
n10sive15-Nov-05 7:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.