之前介绍过Webconfig的具体知识ASP.NET基础知识汇总之WebConfig各节点介绍。今天准备封装一个ConfigHelper类,涉及到了自定义节点的东东,平时虽然一直用,但也没有系统的总结过,网上有很多关于自定义节点的精彩介绍。

一、为什么需要自定义节点?

  大部分情况下,我们都是在<appsetting>中定义自己需要的参数,简单方便。如果配置的参数比较多,比较复杂的话就会显得杂乱无章,而且这种方式不支持复杂的层次节点也不支持强类型,所以有时候我们需要自定义节点。下面我们以配置redis参数和lognet参数为例,介绍自定义节点。

二、通过配置redis参数介绍自定义节点

  先附上完整的配置信息如下

  

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="RedisConfig" type="MyRedisConfigurationHelper.MyRedisConfigurationSection,MyRedisConfigurationHelper" />
<section name="MyLog4net" type="MyLogConfigHelper.MyLog4netClass,MyLogConfigHelper"/>
</configSections>
<RedisConfig autoStart="true" dbIndex="" password="redispass123" allowAdmin="true" abortConnect="false">
<ReadWriteHost>
<add host="127.0.0.1:6379" />
</ReadWriteHost>
<ReadOnlyHost>
<add host="192.168.4.110:6379" />
</ReadOnlyHost>
<MaxWritePoolSize size="" />
<MaxReadPoolSize size="" />
<SocketSendTimeout second="" />
<SocketReceiveTimeout second="" />
<ConnectTimeout second="" />
</RedisConfig>
<MyLog4net>
<add key="LogName" value="Test" />
<add key="LogLevel" value="" />
</MyLog4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="CACHE_REDIS" value="true" />
</appSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" connectionStringName="DefaultConnection" credentialsProvider="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="" connectionStringName="DefaultConnection" />
</providers>
</roleManager>
</system.web>
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source = |SQL/CE|" />
</connectionStrings>
</configuration>

  上边使用颜色标记的信息就是自定义的配置节点。自定义配置节点需要注意的事项如下:

  1、自定义节点必须在configSections节点中。

  2、section节点属性:name:必选的 String 属性,指定与 type 属性中指定的配置节处理程序关联的配置节或元素的名称。这是该元素在配置文件的节设置区域中使用的名称。type:必选的 String 属性,指定用来执行如下操作的配置节处理程序类的名称:处理在 name 属性中指定的节或元素中的配置设置。

  3、section 元素将配置节处理程序与配置元素或节关联。每个 section 元素均标识一个配置节或元素。可以在 sectionGroup 元素中对 section 元素进行逻辑分组,以对 section 元素进行组织并避免命名冲突。section 和 sectionGroup 元素包含在 configSections 元素中。我们在这里没有介绍sectionGroup,毕竟在项目中自定义节点也不多,name不重复即可。

  4、具体的一些特性和元素解释可以参考官网https://docs.microsoft.com/zh-cn/previous-versions/ms228245(v=vs.110)

  5、

三、对自定义节点分块剖析

  上边使用颜色标记的信息就是自定义的配置节点。蓝色标记的是Redis相关的自定义配置节点。绿色的是lognet相关的自定义配置信息。

  1、log4net相关的自定义配置信息解析

    <section name="MyLog4net" type="MyLog4netDemo.MyLog4netClass,MyLog4netDemo"/>

    (1)其中name是配置文件中自定义节点设置区域使用的名称,就是标识设置具体自定义节点所使用的名称。比如:

    

<MyLog4net>
<add key="LogName" value="Test" />
<add key="LogLevel" value="" />
</MyLog4net>

    (2)其中type中的MyLog4netClass就是自定义节点所需要的方法实现。针对于该自定义节点,实现方法如下:

    

    

using System;
using System.Configuration; namespace MyLogConfigHelper
{
/// <summary>
/// 读取自定义配置文件信息
/// </summary>
public class MyLog4netClass : ConfigurationSection
{
private static readonly ConfigurationProperty property
= new ConfigurationProperty(string.Empty, typeof(MyLog4netClassElementCollection), null,
ConfigurationPropertyOptions.IsDefaultCollection); [ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)]
public MyLog4netClassElementCollection KeyValues
{
get
{
return (MyLog4netClassElementCollection)base[property];
}
} #region 读取自定义配置文件信息
private static MyLog4netClass _myLog4netClassProperty = null;
public static MyLog4netClass MyLog4netClassProperty
{
get { return _myLog4netClassProperty; }
set
{
_myLog4netClassProperty = value;
}
}
static MyLog4netClass()
{
const string SETTINGS = "MyLog4net";
object section = null;
if (System.Web.Hosting.HostingEnvironment.IsHosted)
{
//web.config
section = ConfigurationManager.GetSection(SETTINGS);
}
else
{
//App.config
section = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Sections[SETTINGS];
}
if (section is MyLog4netClass)
{
_myLog4netClassProperty = section as MyLog4netClass;
}
if (_myLog4netClassProperty == null)
{
throw new Exception("请在Config文件中配置<configSections> < section name =\"MyLog4net\" type=\"MyLog4netDemo.MyLog4netClass,MyLog4netDemo\"/></configSections>"); }
}
#endregion
} /// <summary>
/// 元素集合
/// </summary>
[ConfigurationCollection(typeof(MyLog4netClassElement))]
public class MyLog4netClassElementCollection : ConfigurationElementCollection
{
public MyLog4netClassElement this[int index]
{
get
{
return (MyLog4netClassElement)base.BaseGet(index);
}
set
{
if (base.BaseGet(index) != null)
{
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}
/// <summary>
/// 重写ConfigurationElementCollection中的方法
/// <summary>
/// <returns></returns>
protected override ConfigurationElement CreateNewElement()
{
return new MyLog4netClassElement();
}
/// <summary>
/// 重写ConfigurationElementCollection中的方法
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
protected override object GetElementKey(ConfigurationElement element)
{
return ((MyLog4netClassElement)element).Key;
}
}
/// <summary>
/// 集合中的每一个元素 实现MyLog4net集合中每一个元素的key value
/// </summary>
public class MyLog4netClassElement : ConfigurationElement
{
public MyLog4netClassElement()
{
}
public MyLog4netClassElement(string key,string value)
{
this.Key = key;
this.Value = value;
}
[ConfigurationProperty("key", IsRequired = true)]
public string Key
{
get
{
return (string)base["key"];
}
set
{
base["key"] = value;
}
}
[ConfigurationProperty("value",IsRequired =true)]
public string Value
{
get
{
return (string)base["value"];
}
set
{
base["value"] = value;
}
}
}
}

    函数入口:

    

using System;

namespace MyLogConfigHelper
{
class Program
{
static void Main(string[] args)
{
MyLog4netClass myLog4netClass = MyLog4netClass.MyLog4netClassProperty;
foreach (MyLog4netClassElement item in myLog4netClass.KeyValues)
{
Console.WriteLine("key:{0}", item.Key);
Console.WriteLine("Value:{0}", item.Value);
}
Console.ReadKey();
}
}
}

  2、RedisConfig相关的自定义节点剖析

  (1)针对RedisConfig的实现代码如下:

  

  

using System;
using System.Configuration; namespace MyRedisConfigurationHelper
{
#region Section 配置文件中 自定义RedisConfig节点的信息Model
public class MyRedisConfigurationSection : ConfigurationSection
{
#region RedisConfig Model信息
[ConfigurationProperty("ReadOnlyHost", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(MyRedisConfigurationElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap, RemoveItemName = "remove")]
public MyRedisConfigurationElementCollection ReadOnlyHost
{
get
{
return (MyRedisConfigurationElementCollection)base["ReadOnlyHost"];
}
} [ConfigurationProperty("ReadWriteHost", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(MyRedisConfigurationElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap, RemoveItemName = "remove")]
public MyRedisConfigurationElementCollection ReadWriteHost
{
get
{
return (MyRedisConfigurationElementCollection)base["ReadWriteHost"];
}
} [ConfigurationProperty("MaxWritePoolSize", IsDefaultCollection = false)]
public MaxWritePoolSizeConfigurationElement MaxWritePoolSize
{
get
{
return (MaxWritePoolSizeConfigurationElement)base["MaxWritePoolSize"];
}
} [ConfigurationProperty("MaxReadPoolSize", IsDefaultCollection = false)]
public MaxWritePoolSizeConfigurationElement MaxReadPoolSize
{
get
{
return (MaxWritePoolSizeConfigurationElement)base["MaxReadPoolSize"];
}
} [ConfigurationProperty("SocketSendTimeout", IsDefaultCollection = false)]
public SocketSendTimeoutConfigurationElement SocketSendTimeout
{
get
{
return (SocketSendTimeoutConfigurationElement)base["SocketSendTimeout"];
}
} [ConfigurationProperty("SocketReceiveTimeout", IsDefaultCollection = false)]
public SocketReceiveTimeoutConfigurationElement SocketReceiveTimeout
{
get
{
return (SocketReceiveTimeoutConfigurationElement)base["SocketReceiveTimeout"];
}
} [ConfigurationProperty("ConnectTimeout", IsDefaultCollection = false)]
public ConnectTimeoutConfigurationElement ConnectTimeout
{
get
{
return (ConnectTimeoutConfigurationElement)base["ConnectTimeout"];
}
} [ConfigurationProperty("autoStart", IsDefaultCollection = false, DefaultValue = true)]
public bool AutoStart
{
get
{
return (bool)base["autoStart"];
}
} [ConfigurationProperty("abortConnect", IsDefaultCollection = false, DefaultValue = true)]
public bool AbortConnect
{
get
{
return (bool)base["abortConnect"];
}
} [ConfigurationProperty("dbIndex", IsDefaultCollection = false, DefaultValue = )]
public int DbIndex
{
get
{
return (int)base["dbIndex"];
}
} [ConfigurationProperty("password", IsDefaultCollection = false, DefaultValue = "")]
public string Password
{
get
{
return (string)base["password"];
}
} [ConfigurationProperty("allowAdmin", IsDefaultCollection = false, DefaultValue = false)]
public bool AllowAdmin
{
get
{
return (bool)base["allowAdmin"];
}
}
#endregion #region 用来获取配置文件中的 自定义RedisConfig节点信息
private static MyRedisConfigurationSection _myRedisConfigurationSectionProperty = null;
public static MyRedisConfigurationSection MyRedisConfigurationSectionProperty
{
get { return _myRedisConfigurationSectionProperty; }
set
{
_myRedisConfigurationSectionProperty = value;
}
} static MyRedisConfigurationSection()
{
const string SETTINGS = "RedisConfig";
object section = null;
if (System.Web.Hosting.HostingEnvironment.IsHosted)
{
//web.config
section = ConfigurationManager.GetSection(SETTINGS);
}
else
{
//App.config
section = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Sections[SETTINGS];
}
if (section is MyRedisConfigurationSection)
{
_myRedisConfigurationSectionProperty = section as MyRedisConfigurationSection;
}
if (_myRedisConfigurationSectionProperty == null)
{
throw new Exception("请在Config文件中配置<configSections> < section name =\"RedisConfig\" type=\"MyRedisConfigurationHelper.GetSectionClass,MyRedisConfigurationHelper\"/></configSections>"); }
}
#endregion
}
#endregion #region ElementCollection 用于接收 自定义RedisConfig多层元素节点
public class MyRedisConfigurationElementCollection: ConfigurationElementCollection
{
public MyRedisConfigurationElement this[int index]
{
get
{
return (MyRedisConfigurationElement)base.BaseGet(index);
}
set
{
if (base.BaseGet(index) != null)
{
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}
protected override ConfigurationElement CreateNewElement()
{
return new MyRedisConfigurationElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((MyRedisConfigurationElement)element).Host;
}
}
#endregion #region Element 集合中的每一个元素 声明RedisConfig集合中每一个元素
/// <summary>
/// host ip地址
/// </summary>
public class MyRedisConfigurationElement:ConfigurationElement
{
public MyRedisConfigurationElement()
{
}
public MyRedisConfigurationElement(string host)
{
this.Host = host;
}
[ConfigurationProperty("host", IsRequired = true)]
public string Host
{
get
{
return (string)base["host"];
}
set
{
base["host"] = value;
}
}
} /// <summary>
/// Socket发送超时的配置信息
/// </summary>
public class SocketSendTimeoutConfigurationElement : TimeoutConfigurationElement
{
}
/// <summary>
/// Socket接收超时的配置信息
/// </summary>
public class SocketReceiveTimeoutConfigurationElement : TimeoutConfigurationElement
{
}
/// <summary>
/// Socket连接超时配置信息
/// </summary>
public class ConnectTimeoutConfigurationElement : TimeoutConfigurationElement
{
} /// <summary>
/// 写入连接池大小的配置信息
/// </summary>
public class MaxWritePoolSizeConfigurationElement : SizeConfigurationElement
{
} /// <summary>
/// 连接池大小的配置信息
/// </summary>
public abstract class SizeConfigurationElement : ConfigurationElement
{
[ConfigurationProperty("size", IsRequired = true, IsKey = true, DefaultValue = )]
public int Size
{
get
{
return (int)base["size"];
}
set
{
base["size"] = value;
}
}
}
/// <summary>
/// Socket超时的配置信息
/// </summary>
public abstract class TimeoutConfigurationElement : ConfigurationElement
{
[ConfigurationProperty("second", IsRequired = true, IsKey = true, DefaultValue = )]
public int Second
{
get
{
return (int)base["second"];
}
set
{
base["second"] = value;
}
}
}
#endregion
}

  (2)函数入口:

  

using System;

namespace MyRedisConfigurationHelper
{
class Program
{
static void Main(string[] args)
{
MyRedisConfigurationSection myRedisConfig = MyRedisConfigurationSection.MyRedisConfigurationSectionProperty;
Console.WriteLine(myRedisConfig.ReadOnlyHost);
Console.ReadKey();
}
}
}

四、代码下载

  其实就是对Element、ElementCollection、Section的操作

  (1)MyLog4net相关代码下载

  (2)RedisConfig相关代码下载

最新文章

  1. Linux下oracle数据库启动和关闭操作
  2. asp.netDataTable导出excel方法(2)
  3. python3 黑板客爬虫闯关游戏(一)
  4. 【vmware vcp 5.1】安装及配置及笔记散记
  5. bzoj1070
  6. PythonCrawl自学日志
  7. NOI题库192 生日蛋糕
  8. 关于 android Intent 传对象和对象数组的一些操作
  9. css样式表的选择器与分类
  10. IpHelper根据客户端IP进行网站分流
  11. Python函数篇(6)-常用模块及简单的案列
  12. HTTP与TCP的关系
  13. mysql插入操作跳过(ignore)、覆盖(replace into)、更新(on duplicate key)
  14. python引入自定义模块
  15. 单片机CPU
  16. python 网络爬虫requests模块
  17. Maven 学习笔记——Maven和Eclipse(2)
  18. 树莓派挂载ntfs优盘
  19. ajax状态码--转他人的
  20. spring boot容器加载完后执行特定操作

热门文章

  1. Beanstalkd工作队列
  2. SQL server 表信息查询
  3. LDAP客户端在Windows环境的部署及配置
  4. #001 Python 00号作业:关于课程
  5. 随笔:WPS居然!出了!Mac版!
  6. .NET Core 必备安全措施
  7. 编译Xposed
  8. mysql之聚合函数、group by、having
  9. web服务器之nginx和apache的区别
  10. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:传值+组件+项目说明