博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET系列:自定义配置节点的复用
阅读量:4308 次
发布时间:2019-06-06

本文共 10931 字,大约阅读时间需要 36 分钟。

appSettings太简单,为每个程序自定义配置节点太复杂,因此要解决app.config&web.config自定义配置的复用问题。

1.读取不依赖SectionName,根节点可以定义为任何名称。

2.足够简单,配置项采用name value的形式;足够复杂,采用树型结构,每个节点都可以有多个配置项和子节点。

3.使用简单,采用路径简化配置项的读取。如: config.Get<string>("root.sub.item-test")。

一、调用方式:

1.配置文件:

2.调用代码:

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

 

3.读取接口定义:IConfig接口定义了配置节点和配置项的读取

public interface IConfig{    INode GetNode(string nodeName);     string Get(string nameOrPath);     T Get
(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
{ protected override ConfigurationElement CreateNewElement() { return new ItemElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((ItemElement)element).Name; } public new IEnumerator
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
Items { get { return this["items"] as ItemElementCollection; } set { this["items"] = value; } } public IEnumerable
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
(string itemName) { return (T)Convert.ChangeType(this.GetItem(itemName), typeof(T)); } } public class NodeElementCollection : ConfigurationElementCollection, IEnumerable
{ protected override ConfigurationElement CreateNewElement() { return new NodeElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((NodeElement)element).Name; } public new IEnumerator
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
Items { get { return this["items"] as ItemElementCollection; } set { this["items"] = value; } } public IEnumerable
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
(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
() .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
(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/

转载于:https://www.cnblogs.com/easygame/p/5051592.html

你可能感兴趣的文章
class里面只能写以下5种
查看>>
《Vim实用技巧》阅读笔记 --- 移动及跳转
查看>>
C# 全角符号转半角
查看>>
python-2:工欲善其事,必先利其器 修改jupyter保存文件目录(亲测)
查看>>
Python 环境搭建
查看>>
免费字典api ,查询汉字完整信息
查看>>
Flume协作框架
查看>>
基于数据库的事务消息解决分布式事务方案
查看>>
HDU 2461 Rectangles#容斥原理
查看>>
网口扫盲二:Mac与Phy组成原理的简单分析(转)
查看>>
使用最大似然法来求解线性模型(1)
查看>>
EF 从sqlserver2008 迁移到 2005出现的BUG
查看>>
架构-浅谈MySQL数据库优化
查看>>
jquery锚点连接划动滚动条,再也不用a标签name 了
查看>>
Apache JMeter--网站自动测试与性能测评
查看>>
信号与系统(中)
查看>>
【iCore4 双核心板_FPGA】例程八:乘法器实验——乘法器使用
查看>>
bash 快捷键
查看>>
检测登录按钮 ,回车即登录
查看>>
蓝桥杯-微生物增殖
查看>>