Sunday, June 14, 2009

.Net Class Library Configuration Files

So, you have a .net class library (or any library which has an file extension .dll) or even an executable file (.exe) that you want to reference in an executable.

In this referenced project you have some configuration settings that you use inside that project but when you run the application you cannot find an easy way to set the settings with the main application (the surrogate app).

For this there are some ways to do (found on web) which has to do with coding, redirecting application configuration files etc and generally reinventing the wheel.

The following is the best solution, which I am using in my projects (and it is strange enough that i couldn't find anyone doing that in the net).

For the demonstration I will be using Visual Studio 2008 (this solution is tested on .Net 2 and .Net 3.5).

Lets say we have a windows forms application named "MyApp", with the following configuration settings:



The configuration file of the application should be as follows:

xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="MyApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        sectionGroup>
    configSections>
    <userSettings>
        <MyApp.Properties.Settings>
            <setting name="test1" serializeAs="String">
                <value>2323value>
            setting>
        MyApp.Properties.Settings>
    userSettings>
configuration>



Also lets say we have a dll project named "MyClassLibrary",
with the following settings:




Its configuration file should be as follows:

xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="MyDllProject.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        sectionGroup>
    configSections>
    <userSettings>
        <MyDllProject.Properties.Settings>
            <setting name="ClassLibraryProperty1" serializeAs="String">
                <value>a propertyvalue>
            setting>
        MyDllProject.Properties.Settings>
    userSettings>
configuration>


Now, in order to access the class library's (MyDllProject) settings from for the surrogate project (MyApp) all we have to do is
copy from the class library configuration file the section:


<
section name="MyDllProject.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />

And append it into the surrogate's configuration sections as follows:

xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="MyApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
            <section name="MyDllProject.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        sectionGroup>
    configSections>
    <userSettings>
        <MyApp.Properties.Settings>
            <setting name="test1" serializeAs="String">
                <value>2323value>
            setting>
        MyApp.Properties.Settings>
    userSettings>
configuration>


After that we will copy the sections properties from the class library configuration file into the surrogate's configuration file as follows:

xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="MyApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
            <section name="MyDllProject.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        sectionGroup>
    configSections>
    <userSettings>
        <MyApp.Properties.Settings>
            <setting name="test1" serializeAs="String">
                <value>2323value>
            setting>
        MyApp.Properties.Settings>
        <MyDllProject.Properties.Settings>
            <setting name="ClassLibraryProperty1" serializeAs="String">
                <value>a propertyvalue>
            setting>
        MyDllProject.Properties.Settings>
    userSettings>
configuration>


That's it!


Now, the dll that is references inside our application will be able to read it's settings from the surrogate's configuration file from its seperate section.

You can test the previous approach be changing the default settings inside the sections settings and see that when your application runs it will load the settings from the surrogate' file.



I have used this approach for Windows Forms applications and ASP.NET apps and it works perfectly.