Home > front end >  How to have custom nested configuration App.Config nodes and section
How to have custom nested configuration App.Config nodes and section

Time:10-07

Here is my code and App.config.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="ExchangeSetting" type="AppWithConfigs.ExchangeSetting, AppWithConfigs"/>
    </configSections>

    <ExchangeSetting>
        <Exchange Name="Binance" ApiKey="B-Key" ApiSecret="B-Secret" ApiPassPhrase="B-Phrase" />
        
        <!-- I CANNOT ADD ANOTHER NODE HERE -->
        <!-- I need to be able to add additional Exchange nodes, but program GIVE EXCEPTION if there is more than 1 -->
        <!--
        <Exchange Name="Coinbase" ApiKey="C-Key" ApiSecret="C-Secret" ApiPassPhrase="C-Phrase" />
        -->
    </ExchangeSetting>
        
</configuration>

And the source code.....

namespace AppWithConfigs
{
    public class ExchangeFeatures : ConfigurationElement
    {
        [ConfigurationProperty("Name", IsRequired = true)]
        public string Name
        {
            get { return (string) this["Name"]; }
            set { value = (string) this["Name"]; }
        }

        [ConfigurationProperty("ApiKey", IsRequired = true)]
        public string ApiKey
        {
            get { return (string)this["ApiKey"]; }
            set { value = (string)this["ApiKey"]; }
        }

        [ConfigurationProperty("ApiSecret", IsRequired = true)]
        public string ApiSecret
        {
            get { return (string)this["ApiSecret"]; }
            set { value = (string)this["ApiSecret"]; }
        }
        [ConfigurationProperty("ApiPassPhrase", IsRequired = false)]
        public string ApiPassPhrase
        {
            get { return (string)this["ApiPassPhrase"]; }
            set { value = (string)this["ApiPassPhrase"]; }
        }
    }

    public class ExchangeSetting : ConfigurationSection
    {
        [ConfigurationProperty("Exchange")]
        public ExchangeFeatures ExchangeFeatures
        {
            get { return (ExchangeFeatures)this["Exchange"]; }
            set { value = (ExchangeFeatures)this["Exchange"];}
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            var st = ConfigurationManager.GetSection("ExchangeSetting") as ExchangeSetting;

            var n = st.ExchangeFeatures.Name;
            var k = st.ExchangeFeatures.ApiKey;
            var s = st.ExchangeFeatures.ApiSecret;
            var p = st.ExchangeFeatures.ApiPassPhrase;

            Console.WriteLine("Name = "   n);
            Console.WriteLine("Key = "   k);
            Console.WriteLine("Secret = "   s);
            Console.WriteLine("PassPhrase = "   p);
        }
    }
}

So i just need to has NESTED Exchange(s) in my ExchangeSetting, but it doenst seem to allow that.... How can i set my config so that it can accept multiple nested nodes and i can parse such info.

I need to be able to get the info in config and loop through to get all the Exchanges settings. But this code only allows ONE setting.

CodePudding user response:

You have ExchangeSetting class which represents the configuration section. ExchangeFeatures represents one configuration element inside the configuration section.

Inside the configuration section you have more than one configuration elements which the same structure. So having public ExchangeFeatures ExchangeFeatures property in the ExchangeSetting will not serve the purpose.

What you need is a type which represent the collection of elements inside the configuration section. Then you can iterate thru that collection to access each of the configuration elements and their attribute values.

So apart from ExchangeSetting and ExchangeFeatures you also need following class to represent the element collections.

public class ExchangeFeaturesCollection : ConfigurationElementCollection
{
    protected override ExchangeFeatures CreateNewElement()
    {
        return new ExchangeFeatures();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((ExchangeFeatures)element).Name;
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get
        {
            return ConfigurationElementCollectionType.BasicMap;
        }
    }

    protected override string ElementName
    {
        get
        {
            return "Exchange";
        }
    }
}

And use the above class in the ExchangeSetting as following.

public class ExchangeSetting : ConfigurationSection
{
    [ConfigurationProperty("", IsRequired = false, IsKey = false, IsDefaultCollection = true)]
    public ExchangeFeaturesCollection ExchangeFeatures
    {
        get { return ((ExchangeFeaturesCollection)(base[""])); }
        set { base[""] = value; }
    }
}

With the above changes you can access the configuration values by doing following.

 var st = ConfigurationManager.GetSection("ExchangeSetting") as ExchangeSetting;
 foreach(var feature in st.ExchangeFeatures.Cast<ExchangeFeatures>())
 {
      Console.WriteLine(feature.Name);
      Console.WriteLine(feature.ApiKey);
      Console.WriteLine(feature.ApiSecret);
      Console.WriteLine(feature.ApiPassPhrase);
 }

I hope this will help you solve your issues.

  • Related