• 自定义ConfigurationSection,创建多个嵌套的ConfigurationElementCollection节点


    本人现在在一家游戏公司,最近在做一个项目,需要做一个GM的管理后台,需要调用其他公司提供的接口,来实现后台管理的操作

    由于接口地址都是固定的,所以想到使用自定义节点,来将接口都配置到web.config中。

    很快,v1.0版本出炉: 

    public class RequestConfigSection : ConfigurationSection
        {
            [ConfigurationProperty("sources", IsDefaultCollection = true)]
            [ConfigurationCollection(typeof(RequestConfigSourceCollection), AddItemName = "add")]
            public RequestConfigSourceCollection ConfigCollection
            {
                get { return (RequestConfigSourceCollection)this["sources"]; }
                set { this["sources"] = value; }
            }
        }
        
        public class RequestConfigSourceCollection : ConfigurationElementCollection
        {
            /// <summary>
            /// 创建新元素
            /// </summary>
            /// <returns></returns>
            protected override ConfigurationElement CreateNewElement()
            {
                return new RequestConfigSource();
            }
    
            /// <summary>
            /// 获取元素的键
            /// </summary>
            /// <param name="element"></param>
            /// <returns></returns>
            protected override object GetElementKey(ConfigurationElement element)
            {
                return ((RequestConfigSource)element).Name;
            }
    
            /// <summary>
            /// 获取所有键
            /// </summary>
            public IEnumerable<string> AllKeys { get { return BaseGetAllKeys().Cast<string>(); } }
    
            /// <summary>
            /// 索引器
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public new RequestConfigSource this[string name]
            {
                get { return (RequestConfigSource)BaseGet(name); }
            }
        }
    
        public class RequestConfigSource : ConfigurationElement
        {
            /// <summary>
            /// 名称
            /// </summary>
            [ConfigurationProperty("name")]
            public string Name
            {
                get { return (string)this["name"]; }
                set { this["name"] = value; }
            }
    
            /// <summary>
            /// 地址
            /// </summary>
            [ConfigurationProperty("url")]
            public string Url
            {
                get { return (string)this["url"]; }
                set { this["url"] = value; }
            }
    
            /// <summary>
            /// 访问类型
            /// </summary>
            [ConfigurationProperty("type")]
            public RequestType RequestType
            {
                get
                {
                    return (RequestType)Enum.Parse(typeof(RequestType), this["type"].ToString(), true);
                }
                set { this["type"] = value; }
            }
        }
    

    在web.config中的配置方式为:

    <apiRequestConfig>
      <sources>
        <add name="..." url="..." type="POST" />
        <add name="..." url="..." type="POST" />
        <add name="..." url="..." type="POST" />
      </sources>
    </apiRequestConfig>
    

     这时候又看了一遍需求文档,发现有说明不同平台的接口地址是不一样的,但接口做的事情是一样的。

    然后就开始想,如果接着在下边追加,则不同平台的同一接口的名称是不能相同的。

    所以想到的理想的配置方式为:

    <apiRequestConfig>
      <sources platform="android">
        <add name="..." url="..." type="POST" />
        <add name="..." url="..." type="POST" />
        <add name="..." url="..." type="POST" />
      </sources>
      <sources platform="ios">
        <add name="..." url="..." type="POST" />
        <add name="..." url="..." type="POST" />
        <add name="..." url="..." type="POST" />
      </sources>
    </apiRequestConfig>
    

     但是sources 名称的节点只能出现一次…好吧,蛋疼了。

    研究尝试了一上午也没有找到合适的解决方式,又懒得再重新写一套代码来读取XML,…开始在网上搜解决方案

    用中文做关键字找不着…翻了墙,用英文来当关键字 one or more ConfigurationElementCollection…

    最终在一老外的博客里找到了一个替代的解决方案,最终的配置为:

    <apiRequestConfig>
        <requestConfigs>
          <request platform="android">
            <sources>
              <add name="..." url="..." type="POST" />
              <add name="..." url="..." type="POST" />
              <add name="..." url="..." type="POST" />
            </sources>
          </request>
          <request platform="ios">
            <sources>
              <add name="..." url="..." type="POST" />
              <add name="..." url="..." type="POST" />
              <add name="..." url="..." type="POST" />
            </sources>
          </request>
        </requestConfigs>
      </apiRequestConfig>
    

    C#代码如下:

    public class RequestConfigSection : ConfigurationSection
        {
            [ConfigurationProperty("requestConfigs", IsDefaultCollection = true)]
            [ConfigurationCollection(typeof(RequestConfigTypeCollection), AddItemName = "request")]
            public RequestConfigTypeCollection ConfigCollection
            {
                get { return (RequestConfigTypeCollection)this["requestConfigs"]; }
                set { this["requestConfigs"] = value; }
            }
    
            /// <summary>
            /// 根据平台和名称获取请求配置信息
            /// </summary>
            /// <param name="name"></param>
            /// <param name="platform"></param>
            /// <returns></returns>
            public RequestConfigSource GetRequestConfigSource(string platform, string name)
            {
                return ConfigCollection[platform].SourceCollection[name];
            }
        }
    
        public class RequestConfigTypeCollection : ConfigurationElementCollection
        {
            /// <summary>
            /// 创建新元素
            /// </summary>
            /// <returns></returns>
            protected override ConfigurationElement CreateNewElement()
            {
                return new RequestConfigType();
            }
    
            /// <summary>
            /// 获取元素的键
            /// </summary>
            /// <param name="element"></param>
            /// <returns></returns>
            protected override object GetElementKey(ConfigurationElement element)
            {
                return ((RequestConfigType)element).Platform;
            }
    
            /// <summary>
            /// 获取所有键
            /// </summary>
            public IEnumerable<string> AllKeys { get { return BaseGetAllKeys().Cast<string>(); } }
    
            /// <summary>
            /// 索引器
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public new RequestConfigType this[string platform]
            {
                get { return (RequestConfigType)BaseGet(platform); }
            }
        }
    
        public class RequestConfigType : ConfigurationElement
        {
            /// <summary>
            /// 获取全部请求配置信息
            /// </summary>
            /// <returns></returns>
            public RequestConfigSource[] GetAllRequestSource()
            {
                var keys = this.SourceCollection.AllKeys;
    
                return keys.Select(name => this.SourceCollection[name]).ToArray();
            }
            /// <summary>
            /// 平台标识
            /// </summary>
            [ConfigurationProperty("platform")]
            public string Platform
            {
                get { return (string)this["platform"]; }
                set { this["platform"] = value; }
            }
    
            [ConfigurationProperty("sources", IsDefaultCollection = true)]
            [ConfigurationCollection(typeof(RequestConfigSourceCollection), AddItemName = "add")]
            public RequestConfigSourceCollection SourceCollection
            {
                get { return (RequestConfigSourceCollection)this["sources"]; }
                set { this["sources"] = value; }
            }
        }
    
        public class RequestConfigSourceCollection : ConfigurationElementCollection
        {
            /// <summary>
            /// 创建新元素
            /// </summary>
            /// <returns></returns>
            protected override ConfigurationElement CreateNewElement()
            {
                return new RequestConfigSource();
            }
    
            /// <summary>
            /// 获取元素的键
            /// </summary>
            /// <param name="element"></param>
            /// <returns></returns>
            protected override object GetElementKey(ConfigurationElement element)
            {
                return ((RequestConfigSource)element).Name;
            }
    
            /// <summary>
            /// 获取所有键
            /// </summary>
            public IEnumerable<string> AllKeys { get { return BaseGetAllKeys().Cast<string>(); } }
    
            /// <summary>
            /// 索引器
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public new RequestConfigSource this[string name]
            {
                get { return (RequestConfigSource)BaseGet(name); }
            }
        }
    
        /// <summary>
        /// 请求的配置信息
        /// </summary>
        public class RequestConfigSource : ConfigurationElement
        {
            /// <summary>
            /// 名称
            /// </summary>
            [ConfigurationProperty("name")]
            public string Name
            {
                get { return (string)this["name"]; }
                set { this["name"] = value; }
            }
    
            /// <summary>
            /// 地址
            /// </summary>
            [ConfigurationProperty("url")]
            public string Url
            {
                get { return (string)this["url"]; }
                set { this["url"] = value; }
            }
    
            /// <summary>
            /// 访问类型
            /// </summary>
            [ConfigurationProperty("type")]
            public RequestType RequestType
            {
                get
                {
                    return (RequestType)Enum.Parse(typeof(RequestType), this["type"].ToString(), true);
                }
                set { this["type"] = value; }
            }
        }
    

    本人的开发环境为 .net framework 4.0

    最初RequestConfigSection 类中的ConfigCollection 和  RequestConfigType 类中的SourceCollection  没有定义ConfigurationCollection特性

    而是在RequestConfigTypeCollectionRequestConfigTypeCollection 中重载了ElementName属性,返回子级的节点名。

    结果抛出节点名未定义的异常…

    改由特性ConfigurationCollection定义,并给特性属性AddItemName赋值为子级的节点名 解决…

    老外博客地址:http://tneustaedter.blogspot.com/2011/09/how-to-create-one-or-more-nested.html  需要FQ访问

    或者直接看这儿,俺给Copy出来了:http://www.cnblogs.com/efenghuo/articles/4022836.html

  • 相关阅读:
    [转]flash builder 4 编译器参数
    三种简洁的经典高效的DIV+CSS制作的Tab导航简析
    《api解读》第三期
    AS3中的条件编译
    比较少见的绘制虚线的方法
    一个关于SharedObject存储位置的讨论
    《api解读》写在前面的话
    wampserver配置本地测试环境_虚拟主机实现多站点
    AS3中的正则表达式 Flex正则表达式
    Flixel引擎学习笔记
  • 原文地址:https://www.cnblogs.com/efenghuo/p/4022818.html
Copyright © 2020-2023  润新知