简体   繁体   English

自定义配置设置,自定义ClientSettingsSection

[英]Custom configuration settings, custom ClientSettingsSection

Consider the following config section:考虑以下配置部分:

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <section name="xxx.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
</configSections>
<applicationSettings>
    <xxx.Properties.Settings>
        <setting name="xxx_Service1" serializeAs="String">
            <value>https://xxx.service1</value>
        </setting>
        <setting name="xxx_Service1" serializeAs="String">
            <value>https://xxx.service2</value>
        </setting>
        <setting name="xxx_Service1" serializeAs="String">
            <value>https://xxx.service3</value>
        </setting>
    </xxx.Properties.Settings>
</applicationSettings>

I try to implement custom version of System.Configuration.ClientSettingsSection .我尝试实现System.Configuration.ClientSettingsSection 的自定义版本。 I need exactly same hierarchy我需要完全相同的层次结构

ConfigSection     
  -  ConfigElement      
  -  ConfigElement     
  -  ConfigElement

Base on code from AssemblyExplorer I wrote custom implementation:基于来自AssemblyExplorer代码,我编写了自定义实现:

{
    static void Main()
    {
        var sec = (CustomClientSettingsSection) ConfigurationManager.GetSection("serviceSettings");
        Console.Read();
    }
}

public class CustomClientSettingsSection : ConfigurationSection
{
    private static readonly ConfigurationProperty _propSettings = new ConfigurationProperty((string)null,
        typeof(CustomSettingElementCollection), (object)null, ConfigurationPropertyOptions.IsDefaultCollection);

    [ConfigurationProperty("", IsDefaultCollection = true)]
    public CustomSettingElementCollection Services
    {
        get { return (CustomSettingElementCollection)this[CustomClientSettingsSection._propSettings]; }
    }
}

public class CustomSettingElementCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new CustomSettingElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((CustomSettingElement)element).Key;
    }
}

public class CustomSettingElement : ConfigurationElement
{
    private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), (object)"", ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey);

    internal string Key
    {
        get
        {
            return this.Name;
        }
    }

    [ConfigurationProperty("name", DefaultValue = "", IsKey = true, IsRequired = true)]
    public string Name
    {
        get
        {
            return (string)this[CustomSettingElement._propName];
        }
        set
        {
            this[CustomSettingElement._propName] = (object)value;
        }
    }
}

I am trying to parse this config.xml我正在尝试解析这个config.xml

  <configSections>
    <section name="serviceSettings" type="ConsoleApplication1.CustomClientSettingsSection, ConsoleApplication1"/>
  </configSections>
  <serviceSettings>
    <setting name="xxx_Service1">
    </setting>
    <setting name="xxx_Service2">
    </setting>
  </serviceSettings>

I get error:我得到错误:

Unrecognized element 'setting'.无法识别的元素“设置”。

How to parse this config and get list of configElement with same attribute?如何解析此配置并获取具有相同属性的configElement列表?

This is code I adapted from here to fit your example.这是我从这里改编的代码以适合您的示例。

Code Project: Custom Configuration Sections in app.config or web.config 代码项目:app.config 或 web.config 中的自定义配置部分

I use Powershell and VS Code to test C# code我使用 Powershell 和 VS Code 来测试 C# 代码

csc TestCodeApp.cs
.\TestCodeApp.exe

TestCodeApp.exe.config TestCodeApp.exe.config

<configuration>
    <configSections>
        <section name="Services" type="TestCodeApp.ServicesConfig, TestCodeApp"/>
    </configSections>
    <Services>
        <setting name="xxx_Service1" value="this1"/>
        <setting name="xxx_Service2" value="this2"/>
    </Services>
</configuration>

TestCodeApp.cs测试代码应用程序

using System;
using System.Configuration;
using System.Diagnostics;

namespace TestCodeApp {

    class TestCode {
        static void Main () {
            ExeConfigurationFileMap configMap = new ExeConfigurationFileMap { ExeConfigFilename = "TestCodeApp.exe.config" };
            Configuration config = ConfigurationManager.OpenMappedExeConfiguration (configMap, ConfigurationUserLevel.None);

            var section = (ServicesConfig) config.GetSection ("Services");

            // This fixes the below error
            // error CS0122: 'System.Configuration.ConfigurationElement.this[System.Configuration.ConfigurationProperty]' is inaccessible due to its protection level
            section.SectionInformation.UnprotectSection ();

            var services = section.Services;

            for (int i = 0; i < services.Count; i++)
            {
                Console.WriteLine(services[i].Name + " - " + services[i].Value);
            }            
        }
    }

    public class ServicesConfig : ConfigurationSection {
        [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
        [ConfigurationCollection(typeof(ServicesCollection), AddItemName = "setting")]
        public ServicesCollection Services {
            get { return ((ServicesCollection) (this[""])); }
        }
    }

    [ConfigurationCollection (typeof (ServicesElement))]
    public class ServicesCollection : ConfigurationElementCollection {
        protected override ConfigurationElement CreateNewElement () {
            return new ServicesElement ();
        }

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

        public ServicesElement this [int index] {
            get {
                return (ServicesElement) BaseGet (index);
            }
        }
    }

    public class ServicesElement : ConfigurationElement {
        [ConfigurationProperty ("name", DefaultValue = "",
            IsKey = true, IsRequired = true)]
        public string Name {
            get {
                return ((string) (base["name"]));
            }
            set {
                base["name"] = value;
            }
        }

        [ConfigurationProperty ("value", DefaultValue = "",
            IsKey = false, IsRequired = false)]
        public string Value {
            get {
                return ((string) (base["value"]));
            }
            set {
                base["value"] = value;
            }
        }      
    }
}

I tested it and it works nicely.我对其进行了测试,效果很好。 Let me know if you have questions.如果您有任何疑问,请告诉我。

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

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