自定义ConfigurationSection,创建多个嵌套的Co

系统 1652 0

本人现在在一家游戏公司,最近在做一个项目,需要做一个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 特性

而是在 RequestConfigTypeCollection RequestConfigTypeCollection 中重载了 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

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


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论