简体   繁体   English

如何拥有自定义嵌套配置 App.Config 节点和部分

[英]How to have custom nested configuration App.Config nodes and section

Here is my code and App.config.这是我的代码和 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.所以我只需要在我的 ExchangeSetting 中有 NESTED Exchange(s),但它似乎允许这样做......我如何设置我的配置以便它可以接受多个嵌套节点并且我可以解析这些信息。

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.但是这段代码只允许一个设置。

You have ExchangeSetting class which represents the configuration section.您有ExchangeSetting class 表示配置部分。 ExchangeFeatures represents one configuration element inside the configuration section. ExchangeFeatures表示配置部分中的一个配置元素。

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.因此,在 ExchangeSetting 中拥有public ExchangeFeatures ExchangeFeatures属性将无法达到目的。

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.因此,除了ExchangeSettingExchangeFeatures之外,您还需要遵循 class 来表示元素 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.并在ExchangeSetting中使用上面的 class,如下所示。

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.我希望这会帮助您解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM