Pages

Showing posts with label config. Show all posts
Showing posts with label config. Show all posts

Tuesday, November 13, 2012

Implementing Custom Config Section - Part 2

This is the Part Two of "Implementing Custom Config Section". You can visit Part One here.

In part one, we looked at config sections that have non-repeating name value pairs.The config section we would like to have here have repeated name value pairs, added to the section using <add>  similar to appSettings section. So, lets get started.

Step 1 - Define your configuration section

Add your configuration section to your web.config, app.config, or machine.config file. I have mine setup as follows:
<MyConfig>
    <MyConfigSettings>
      <add key="1" setting1="setting11" setting2="setting12" />
      <add key="2" setting1="setting21" setting2="setting22" />
      <add key="3" setting1="setting31" setting2="setting32" />
    </MyConfigSettings>
</MyConfig>
Note: You need to have a wrapper element around your settings, in this case <MyConfig>.


Step 2 - Define a class for your elements

The second step is to define a class that inherits from System.Configuration.ConfigurationElement describing each element inside <add> as a property. It looks like:

  public class MyConfigElement : System.Configuration.ConfigurationElement
    {
        [System.Configuration.ConfigurationProperty("key", IsRequired = true)]
        public string Key
        {
            get
            {
                return this["key"as string;
            }
        }
 
        [System.Configuration.ConfigurationProperty("setting1", IsRequired = true)]
        public string Setting1
        {
            get
            {
                return this["setting1"as string;
            }
        }
 
        [System.Configuration.ConfigurationProperty("setting2", IsRequired = true)]
        public string Setting2
        {
            get
            {
                return this["setting2"as string;
            }
        }
    }

Step 3 - Define a class for your setting element

The third step is to define a class that inherits from System.Configuration.ConfigurationElementCollection. This is the class that will represent the collection of your settings.

  public class MyConfigSetting : System.Configuration.ConfigurationElementCollection
    {
        public MyConfigElement this[int index]
        {
            get
            {
                return base.BaseGet(index) as MyConfigElement;
            }
            set
            {
                if (base.BaseGet(index) != null)
                {
                    base.BaseRemoveAt(index);
                }
                this.BaseAdd(index, value);
            }
        }
 
        protected override System.Configuration.ConfigurationElement CreateNewElement()
        {
            return new MyConfigElement();
        }
 
        protected override object GetElementKey(System.Configuration.ConfigurationElement element)
        {
            return ((MyConfigElement)element).Key;
        }
    }
Note: Notice how it will be accessing your elements using the key element. You can name the key anything you like, but it must be unique, and returned from  GetElementKey() method.

Step 4 - Define a class for your custom section

The fourth step is to define a class that represents your custom section. This has to inherit from System.Configuration.ConfigurationSection. The important thing to notice here is the section/element name you have used to define your custom config will be used.

namespace Brinks.CompuSafe.SafeServer.Web.Internal
{
    public class MyConfig : System.Configuration.ConfigurationSection
    {
        // The section name used in config file
        private static string sectionName = "MyConfig";
 
        public static MyConfig GetConfig()
        {
            return (MyConfig) System.Configuration.ConfigurationManager.GetSection(MyConfig.sectionName) ??
                   new MyConfig();
        }
 
        // The settings name used in config file
        [System.Configuration.ConfigurationProperty("MyConfigSettings")]
        public MyConfigSetting MyConfigSettings
        {
            get { return (MyConfigSettingthis["MyConfigSettings"] ?? new MyConfigSetting(); }
        }
    }
}

Step 5 - Define the section group in configSection

The final step is to add the section name definition in configSections of the config file as follows:
<configSections>
    <section name="MyConfig" type="BlogTestSample.MyConfig, BlogTestSample"/>
</configSections>
The type has two params: the full namespace(namespace with class), and assembly name.

Accessing Settings

To access it is really simple:
var settings = MyConfig.GetConfig().MyConfigSettings;
foreach (MyConfigElement element in settings)
{
    Console.WriteLine(element.Key);
    Console.WriteLine(element.Setting1);
    Console.WriteLine(element.Setting2);
}
Here's a screenshot in debug mode:

Tuesday, October 16, 2012

Implementing Custom Configuration Section - Part 1

.Net has made adding, and reading configurations from config files, app.config, web.config, machine.config, really simple. You can use appSettings sections to manage name value pair config, and connectionStrings sections to manage the connections strings to database. But, it has also provided a really simple way to create your own custom sections, and read it from the code. There are various reason why you want to do this way if appSettings does not fit your need. It's more readable, understandable. I will let you decide on the reasons :).

The code is really simple, so I will not go through it completely, however I will point out some interesting stuffs along the way. So, here you go. Here's a custom configuration section I want to build for.

<MyConfig
    Config1="Config1"
    Config2="Config2" 
    Config3="Config3"/>

And here's the class that can read the values from it:

using System.Configuration;
 
namespace BlogTestSample
{
    public class MyConfig : ConfigurationSection
    {
        private static MyConfig myConfig = ConfigurationManager.GetSection("MyConfig"as MyConfig;
 
        // private configuration properties
        [ConfigurationProperty("Config1", IsRequired = true)]
        private string config1 { get { return (stringthis["Config1"]; } }
 
        [ConfigurationProperty("Config2", IsRequired = true)]
        private string config2 { get { return (string)this["Config2"]; } }
 
        [ConfigurationProperty("Config3", IsRequired = true)]
        private string config3 { get { return (string)this["Config3"]; } }
 
        // public accessors
        public static string Config1 { get { return myConfig.config1; } }
        public static string Config2 { get { return myConfig.config2; } }
        public static string Config3 { get { return myConfig.config3; } }
    }
}

You also need to add the section name definition in configSections of the config file as follows:

<configSections>
    <section name="MyConfig" type="BlogTestSample.MyConfig, BlogTestSample"/>
</configSections>
The type has two params: the full namespace(namespace with class), and assembly name.

Some things to notice here:
  • The class inherits from ConfigurationSection. This basically tells the framework that it is a custom configuration section handler. 
  • The class name matches with the section name, but it doesn't have to. What we need to make sure is the parameter to GetSection() in fifth line must be same as the section name.
  • Each private string represents the configuration property in the config section. 
  • Each public string represents the getter for the private string.
  • If you have other types like int, decimal, just parse, and return the type back.
  • You can use the same format, if you have a config section inside a config section. In this case, your return type is the class that represents the config section.