Jordi
Jordi

Reputation: 23187

read array in a config file in C#

By now, I'm using a configuration file like this in order to set which environtment my application must to work with:

<configuration>
  <appSettings>
    <add key="environment" value="demo"/>
  </appSettings>
</configuration>

I'm reading it as follow:

AppSettingsSection appSettings = ConfigurationManager.OpenExeConfiguration( 
    (System.Reflection.Assembly.GetAssembly(typeof(LESTBackend))).Location).AppSettings;

From now then, I need to modify the configuration file in order to let whoever who want add some more information like host, and port. I need to say my application is connecting to two endpoints, so using the old xml style I'd need something like this:

    <endpoints>
      <webapi host="hhh" port="1111"/>
      <authz host="hhh2" port="2222"/>
    </endpoints>

How could I add this information to my configuration file, and how could I read it?

Up to now, I've been able to create from classes in order to abstract my configuration sections and elements:

Main section (BackendSection):

public class BackendSection : ConfigurationSection
{
    public const string BACKEND_ATTRIBUTE = "backend";

    [ConfigurationProperty(BackendSection.BACKEND_ATTRIBUTE, IsRequired = true)]
    public ScopeElement Scope
    {
        get
        {
            return (ScopeElement)this[BackendSection.BACKEND_ATTRIBUTE];
        }
        set
        {
            this[BackendSection.BACKEND_ATTRIBUTE] = value;
        }
    }
}

So, each BackendSection contains one ScopeElement. Each ScopeElement has a scope name an array of EndpointElements:

public class ScopeElement : ConfigurationElement
{

    public const string SCOPE_ATTRIBUTE = "scope";
    public const string ENDPOINTS_ATTRIBUTE = "endpoints";
    public const string ENDPOINT_ATTRIBUTE = "endpoint";

    [ConfigurationProperty(ScopeElement.SCOPE_ATTRIBUTE, IsRequired = true)]
    public string Scope
    {
        get
        {
            return this[ScopeElement.SCOPE_ATTRIBUTE] as string;
        }
    }

    [ConfigurationProperty(ScopeElement.ENDPOINTS_ATTRIBUTE, IsRequired = false)]
    [ConfigurationCollection(typeof(EndpointsCollectionElements), AddItemName = ScopeElement.ENDPOINT_ATTRIBUTE)]
    public EndpointsCollectionElements Endpoints
    {
        get
        {
            return (EndpointsCollectionElements)this[ScopeElement.ENDPOINTS_ATTRIBUTE];
        }
    }

}

So,

public class EndpointsCollectionElements : ConfigurationElementCollection
{
    public EndpointElement this[int index]
    {
        get
        {
            return base.BaseGet(index) as EndpointElement;
        }

        set
        {
            if (base.BaseGet(index) != null)
                base.BaseRemoveAt(index);

            this.BaseAdd(index, value);
        }
    }

    public new EndpointElement this[string responseString]
    {
        get { return (EndpointElement)BaseGet(responseString); }
        set
        {
            if (this.BaseGet(responseString) != null)
                this.BaseRemoveAt(this.BaseIndexOf(this.BaseGet(responseString)));

            BaseAdd(value);
        }
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new EndpointElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((EndpointElement)element).App;
    }
}

And EndpointElement:

public class EndpointElement : ConfigurationElement
{

    public const string HOST_ATTRIBUTE = "host";
    public const string PORT_ATTRIBUTE = "port";
    public const string APP_ATTRIBUTE = "app";

    [ConfigurationProperty(EndpointElement.HOST_ATTRIBUTE, IsRequired = false)]
    public string Host
    {
        get
        {
            return this[EndpointElement.HOST_ATTRIBUTE] as string;
        }
    }

    [ConfigurationProperty(EndpointElement.PORT_ATTRIBUTE, IsRequired = false)]
    public int Port
    {
        get
        {
            return (int)this[EndpointElement.PORT_ATTRIBUTE];
        }
    }

    [ConfigurationProperty(EndpointElement.APP_ATTRIBUTE, IsRequired = false)]
    public int App
    {
        get
        {
            return (int)this[EndpointElement.APP_ATTRIBUTE];
        }
    }
}

Could anybody tell me how to write a .config file and how to read it using these classes?

This .config file would be right?

<configuration>
  <configSections>
    <section name="backend" type="Backend.Implementations.Lest.Settings.BackendSection"
  </configSections>
  <backend scope="QA">
      <endpoints>
        <endpoint host="localhost" port="1111" app="webapi"/>
        <endpoint host="localhost" port="2222" app="authz"/>
      </endpoints>
    </backend>
</configuration>

Upvotes: 0

Views: 2142

Answers (1)

toadflakz
toadflakz

Reputation: 7944

You need to create a custom configuration section.

There's the MSDN: How To : How to: Custom Configuration Sections

As an aside, unless you're opening a configuration file for another executeable, you can just use ConfigurationManager.AppSettings[""] to reference the currently executing configuration file AppSettings section.

Upvotes: 1

Related Questions