亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ASP.NET系列:自定義配置節點的復用

2019-11-14 14:23:31
字體:
來源:轉載
供稿:網友

appSettings太簡單,為每個程序自定義配置節點太復雜,因此要解決app.config&web.config自定義配置的復用問題。

1.讀取不依賴SectionName,根節點可以定義為任何名稱。

2.足夠簡單,配置項采用name value的形式;足夠復雜,采用樹型結構,每個節點都可以有多個配置項和子節點。

3.使用簡單,采用路徑簡化配置項的讀取。如: config.Get<string>("root.sub.item-test")。

一、調用方式:

1.配置文件:

<?xml version="1.0" encoding="utf-8" ?><configuration>  <configSections>    <section name="node" type="Onion.Configuration.AppConfig.ConfigSection,Onion.Configuration" />  </configSections>  <node name="root">    <items>      <item name="version" value="1.0.0.1" />    </items>    <nodes>      <node name="runtime">        <items>          <item name="debug" value="false" />          <item name="ioc" value="IoC.Contianer.StructureMapIoC" />        </items>      </node>      <node name="upload">        <items>          <item name="auth" value="true" />          <item name="path" value="~/upload" />          <item name="url" value="~/Upload/Index" />        </items>      </node>      <node name="captcha">        <items>          <item name="timeout" value="3000" />          <item name="url" value="~/Captcha/Index" />        </items>      </node>      <node name="oauth2">        <items>          <item name="disabled" value ="false" />          <item name="callback" value ="/Home/ExternalLoginCallBack? />        </items>        <nodes>          <node name="QQclient">            <items>              <item name="disabled" value="false" />              <item name="method" value="get" />              <item name="key" value="9233e24d" />              <item name="secret" value="1ac35907-7cfa-4079-975c-959b98d23a95" />            </items>          </node>          <node name="weiboclient">            <items>              <item name="disabled" value="true" />              <item name="method" value="post" />              <item name="key" value="0cdea8f3" />              <item name="secret" value="dc679dbb-7e75-44f7-a99e-5359259fc94b" />            </items>          </node>        </nodes>      </node>    </nodes>  </node></configuration>

2.調用代碼:

[Fact]        public void Tests()        {            var config = new AppConfigAdapter();            Assert.True(config.Get<string>("version") == "1.0.0.1");            Assert.True(config.Get<bool>("runtime.debug") == false);            Assert.True(config.Get<string>("runtime.ioc") == "IoC.Contianer.StructureMapIoC");            Assert.True(config.Get<bool>("upload.auth") == true);            Assert.True(config.Get<string>("upload.path") == "~/upload");            Assert.True(config.Get<string>("upload.url") == "~/Upload/Index");            Assert.True(config.Get<int>("captcha.timeout") == 3000);            Assert.True(config.Get<string>("captcha.url") == "~/Captcha/Index");            Assert.True(config.Get<bool>("oauth2.disabled") == false);            Assert.True(config.Get<string>("oauth2.callback") == "/Home/ExternalLoginCallBack?ProviderName=");            Assert.True(config.GetNode("oauth2").Nodes.Any(o => o.GetItem<bool>("disabled")));            foreach (var node in config.GetNode("oauth2").Nodes)            {                if (node.Name == "qqclient")                {                    Assert.True(node.GetItem<bool>("disabled") == false);                    Assert.True(node.GetItem<string>("method") == "get");                    Assert.True(node.GetItem<string>("key") == "9233e24d");                    Assert.True(node.GetItem<string>("secret") == "1ac35907-7cfa-4079-975c-959b98d23a95");                }                else if (node.Name == "weiboclient")                {                    Assert.True(node.GetItem<bool>("disabled") == true);                    Assert.True(node.GetItem<string>("method") == "post");                    Assert.True(node.GetItem<string>("key") == "0cdea8f3");                    Assert.True(node.GetItem<string>("secret") == "dc679dbb-7e75-44f7-a99e-5359259fc94b");                }            }        }

二、接口定義:

1.配置項定義:IItem接口定義最基礎的配置項,只包含Name和Value屬性。

public interface IItem{    string Name { get; set; }     string Value { get; set; }}

2.配置節點定義:INode接口定義了配置節點的樹形結構

public interface INode{    string Name { get; set; }     IEnumerable<IItem> Items { get; set; }     IEnumerable<INode> Nodes { get; set; }     string GetItem(string itemName);     T GetItem<T>(string itemName);}

 

3.讀取接口定義:IConfig接口定義了配置節點和配置項的讀取

public interface IConfig{    INode GetNode(string nodeName);     string Get(string nameOrPath);     T Get<T>(string nameOrPath);}

以上3個接口定義了所有的邏輯。

三、接口實現:

1.自定義ItemElement(IItem)和ItemElementCollection用于實現單個節點的配置項讀取。

    public class ItemElement : ConfigurationElement, IItem    {        [ConfigurationProperty("name", IsRequired = true)]        public string Name        {            get { return Convert.ToString(this["name"]); }            set { this["name"] = value; }        }        [ConfigurationProperty("value", IsRequired = true)]        public string Value        {            get { return Convert.ToString(this["value"]); }            set { this["value"] = value; }        }    }    public class ItemElementCollection : ConfigurationElementCollection, IEnumerable<IItem>    {        protected override ConfigurationElement CreateNewElement()        {            return new ItemElement();        }        protected override object GetElementKey(ConfigurationElement element)        {            return ((ItemElement)element).Name;        }        public new IEnumerator<IItem> GetEnumerator()        {            for (int i = 0; i < base.Count; i++)            {                yield return base.BaseGet(i) as IItem;            }        }    }
View Code

 

2.自定義NodeElement(INode)和NodeElementCollection用于實現節點樹功能。

    public class NodeElement : ConfigurationElement, INode    {        [ConfigurationProperty("name", IsRequired = true)]        public string Name        {            get { return Convert.ToString(this["name"]); }            set { this["name"] = value; }        }        [ConfigurationProperty("items")]        [ConfigurationCollection(typeof(ItemElementCollection), AddItemName = "item")]        public ItemElementCollection ItemElements        {            get            {                return this["items"] as ItemElementCollection;            }            set { this["items"] = value; }        }        [ConfigurationProperty("nodes")]        [ConfigurationCollection(typeof(NodeElementCollection), AddItemName = "node")]        public NodeElementCollection NodeElements        {            get            {                return this["nodes"] as NodeElementCollection;            }            set { this["nodes"] = value; }        }        public IEnumerable<IItem> Items        {            get            {                return this["items"] as ItemElementCollection;            }            set { this["items"] = value; }        }        public IEnumerable<INode> Nodes        {            get            {                return this["nodes"] as NodeElementCollection;            }            set { this["nodes"] = value; }        }        public string GetItem(string itemName)        {            return this.Items.FirstOrDefault(o => o.Name == itemName)?.Value;        }        public T GetItem<T>(string itemName)        {            return (T)Convert.ChangeType(this.GetItem(itemName), typeof(T));        }    }    public class NodeElementCollection : ConfigurationElementCollection, IEnumerable<INode>    {        protected override ConfigurationElement CreateNewElement()        {            return new NodeElement();        }        protected override object GetElementKey(ConfigurationElement element)        {            return ((NodeElement)element).Name;        }        public new IEnumerator<INode> GetEnumerator()        {            for (int i = 0; i < base.Count; i++)            {                yield return base.BaseGet(i) as INode;            }        }    }
View Code

 

3.自定義ConfigSection實現配置節點和配置項讀取。

    public class ConfigSection : ConfigurationSection, INode    {        [ConfigurationProperty("name", IsRequired = true)]        public string Name        {            get { return Convert.ToString(this["name"]); }            set { this["name"] = value; }        }        [ConfigurationProperty("items")]        [ConfigurationCollection(typeof(ItemElementCollection), AddItemName = "item")]        public ItemElementCollection ItemElements        {            get            {                return this["items"] as ItemElementCollection;            }            set { this["items"] = value; }        }        [ConfigurationProperty("nodes")]        [ConfigurationCollection(typeof(NodeElementCollection), AddItemName = "node")]        public NodeElementCollection NodeElements        {            get            {                return (NodeElementCollection)this["nodes"];            }            set { this["nodes"] = value; }        }        public IEnumerable<IItem> Items        {            get            {                return this["items"] as ItemElementCollection;            }            set { this["items"] = value; }        }        public IEnumerable<INode> Nodes        {            get            {                return (NodeElementCollection)this["nodes"];            }            set { this["nodes"] = value; }        }        public string GetItem(string itemName)        {            return this.Items.FirstOrDefault(o => o.Name == itemName)?.Value;        }        public T GetItem<T>(string itemName)        {            return (T)Convert.ChangeType(this.GetItem(itemName), typeof(T));        }    }
View Code

 

4.自定義AppConfigAdapter實現IConfig接口。

    public class AppConfigAdapter : IConfig    {        private INode _section;        public AppConfigAdapter()        {            var sectionName = (HostingEnvironment.IsHosted ? WebConfigurationManager.OpenWebConfiguration("~") : ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None))                .Sections.Cast<ConfigurationSection>()                .FirstOrDefault(o => o.SectionInformation.Type.IndexOf("Onion.Configuration.AppConfig.ConfigSection") != -1)                .SectionInformation.Name ?? "Node";            _section = (INode)ConfigurationManager.GetSection(sectionName);        }        public INode GetNode(string nodeName)        {            return this.GetNode(nodeName, this._section);        }        public string Get(string nameOrPath)        {            if (nameOrPath.IndexOf('.') == -1)            {                return this._section.Items.FirstOrDefault(o => o.Name == nameOrPath)?.Value;            }            var nodeItemPath = nameOrPath.Split('.');            var node = this.GetNode(nodeItemPath.FirstOrDefault());            var nodeNameList = nodeItemPath.Skip(1).Take(nodeItemPath.Length - 2);            if (node != null)            {                foreach (var item in nodeNameList)                {                    if (node.Nodes.Any(o => o.Name == item))                    {                        node = node.Nodes.FirstOrDefault(o => o.Name == item);                    }                    else                    {                        throw new System.ArgumentException(string.Format("node name {0} error", item));                    }                }                return node.Items.FirstOrDefault(o => o.Name == nodeItemPath.LastOrDefault()).Value;            }            return null;        }        public T Get<T>(string nameOrPath)        {            var value = this.Get(nameOrPath);            return (T)Convert.ChangeType(value, typeof(T));        }        #region private        private INode GetNode(string nodeName, INode node)        {            INode result = null;            if (node.Name == nodeName)            {                return node;            }            else if (node.Nodes.Any())            {                foreach (var item in node.Nodes)                {                    result = GetNode(nodeName, item);                    if (result != null)                    {                        break;                    }                }            }            return result;        }        #endregion private    }
View Code

 

Nuget:https://www.nuget.org/packages/Onion.Configuration/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品欧美日韩| 精品久久久久久| 97涩涩爰在线观看亚洲| 国产成人精品一区二区三区| 成人h视频在线观看播放| 欧美一级大片视频| 国产91对白在线播放| www日韩中文字幕在线看| 中文字幕日韩精品在线| 亚洲精品色婷婷福利天堂| 中文字幕在线看视频国产欧美在线看完整| 亚洲电影免费观看| 青青久久av北条麻妃黑人| 亚洲性夜色噜噜噜7777| 欧美日韩裸体免费视频| 久久久精品2019中文字幕神马| 5278欧美一区二区三区| 欧美性资源免费| 精品久久中文字幕久久av| 欧美大片第1页| 欧美国产在线视频| 亚洲欧美成人网| 久久天堂电影网| 美女精品视频一区| 欧日韩不卡在线视频| 国产在线98福利播放视频| 丝袜美腿亚洲一区二区| 亚洲伦理中文字幕| 成人在线精品视频| 亚洲欧美国产va在线影院| 欧美大秀在线观看| 亚洲石原莉奈一区二区在线观看| 欧美精品生活片| 福利微拍一区二区| www.久久草.com| 成人欧美一区二区三区在线| 亚洲欧美制服另类日韩| 欧美国产日韩二区| 69久久夜色精品国产69乱青草| 国产国语刺激对白av不卡| 庆余年2免费日韩剧观看大牛| 亚洲色图偷窥自拍| 国产成人一区二区| 精品久久久国产| 好吊成人免视频| 亚洲欧美成人一区二区在线电影| 亚洲色图色老头| 亚洲黄色av网站| 亚洲精品免费一区二区三区| 色999日韩欧美国产| 欧美日韩黄色大片| 国产精品精品视频| 亚洲自拍在线观看| 日韩亚洲欧美中文高清在线| 欧美裸体男粗大视频在线观看| 精品国产欧美一区二区三区成人| 91精品国产九九九久久久亚洲| 色老头一区二区三区| 日韩视频―中文字幕| 中文字幕精品国产| 亚洲欧美在线x视频| 91免费高清视频| 亚洲一区二区精品| 国产精品入口日韩视频大尺度| 色久欧美在线视频观看| 青草青草久热精品视频在线观看| xxxxx91麻豆| 日韩69视频在线观看| 国产精品美女久久久免费| 国内自拍欧美激情| 欧美福利在线观看| 91系列在线播放| 日韩av在线不卡| 国产精品吴梦梦| 国产第一区电影| 国产精品99久久久久久www| 欧美一区在线直播| 北条麻妃99精品青青久久| 亚洲精品99久久久久| 国产精选久久久久久| 欧美激情久久久| 色999日韩欧美国产| 成人伊人精品色xxxx视频| 清纯唯美日韩制服另类| 亚洲最大福利网站| 国产精品高潮呻吟久久av黑人| 欧美日韩性生活视频| 日韩av在线一区二区| 91免费视频网站| 在线性视频日韩欧美| 国产香蕉一区二区三区在线视频| 亚洲色图15p| 一区二区三区在线播放欧美| 丰满岳妇乱一区二区三区| 亚洲成人精品久久久| 国产精品免费一区| 亚洲女人初尝黑人巨大| 欧美丝袜美女中出在线| 日韩性xxxx爱| 欧美区二区三区| 国产z一区二区三区| 91av在线网站| 国产成人鲁鲁免费视频a| 久久青草福利网站| 国产精品久久久久免费a∨大胸| 国产日韩换脸av一区在线观看| 欧美性猛交xxxx免费看久久久| 国产精品扒开腿做爽爽爽的视频| 欧美午夜激情在线| 国内外成人免费激情在线视频网站| 亚洲一区二区国产| 欧美国产一区二区三区| 精品美女永久免费视频| 中文字幕欧美日韩va免费视频| 久久亚洲私人国产精品va| 精品久久久一区| 97超碰蝌蚪网人人做人人爽| 亚洲区在线播放| 国外成人在线直播| 欧美日韩美女在线观看| 亚洲二区中文字幕| 最近中文字幕日韩精品| 精品丝袜一区二区三区| 成人自拍性视频| 欧洲亚洲妇女av| 国产精品一区久久久| 欧美国产日本在线| 国产精品一区二区久久久久| 91超碰中文字幕久久精品| 日韩欧美国产骚| 国产中文字幕91| 国产69久久精品成人| 亚洲风情亚aⅴ在线发布| 色偷偷91综合久久噜噜| 亚洲激情视频在线播放| 欧美性受xxx| 韩剧1988免费观看全集| 欧美高跟鞋交xxxxhd| 国产成人亚洲综合91精品| 亚洲精品视频在线播放| 国产精品极品在线| 久久成人18免费网站| 国产成人一区二区三区电影| 日韩一区在线视频| 福利一区福利二区微拍刺激| www.亚洲成人| 欧美理论电影网| 国产精品永久免费视频| 国产精品96久久久久久| 欧美性视频网站| 欧美成人性生活| 日韩视频亚洲视频| 国产成人拍精品视频午夜网站| 久久久亚洲成人| 欧美日产国产成人免费图片| 日韩小视频在线| 亚洲精品国产suv| 国产精品极品尤物在线观看| 欧美日韩国产成人高清视频| 亚洲美女av黄| 亚洲国产高清福利视频| 亚洲视频axxx| 国内精品视频在线| 中文字幕无线精品亚洲乱码一区|