前一篇博文中,老周介绍了自定义配置节的方法,本文咱们再往深一层,再看看如何在自定义的配置节中使用配置元素集合。

前面咱们说过,Configuration Section是特殊的配置元素,它可以包装一类功能,并且在使用前,必须在配置文件中注册其类型。只有作为配置节的元素才需要从 ConfigurationSection 类派生,而对配置节下面的普通配置元素,只需要从 ConfigurationElement 类派生即可。

要在配置中使用元素集合,必须实现 ConfigurationElementCollection 抽象类,并实现或覆写需要的成员。其中,有两个抽象方法你必须要实现的:

1、CreateNewElement:返回集合中所包含的配置元素的实例,ConfigurationElement是公共基类,而实际要返回的是你自己定义的配置元素的实例。

2、GetElementKey:实现该方法,你可以按照你的思维,返回一个对象实例,作为集合中某个元素的标识,该返回值用来管理集合中的元素,当要检索元素时,就是通过这个返回的key来查找的。

在自定义的配置节类(从 ConfigurationSection 类派生的类)中,通过一个属性来公开集合对象(集合对象须实现 ConfigurationElementCollection 类),此属性的声明方法与上一篇文章中所讲述的配置属性定义一样。

好了,依老周一惯作风,下面给各位上一个实例。

先简单介绍一下我写的这个配置节,它公开一个 servers 属性,该属性是一个集合,每个集合中的元素可以单独配置服务器信息,host 表示服务主机名,port 表示服务器开放的端口号。

第一步要实殃一个普通元素,用来配置单条服务器信息,包括主机名和端口号。

    public class SvItem : ConfigurationElement
{
[ConfigurationProperty("host", DefaultValue = "localhost")]
public string Hostname
{
get { return (string)this["host"]; }
set { this["host"] = value; }
} [ConfigurationProperty("port", DefaultValue = "")]
public int Port
{
get { return (int)this["port"]; }
set { this["port"] = value; }
}
}

注意,上一篇烂文中讲过的,ConfigurationPropertyAttribute 不要忘了,而且名字要与类索引器中的参数相同。这是个很普通很平凡很卑微的配置元素,所以从 ConfigurationElement 类派生即可。

接着,需要实现我们自定义的配置元素集合类。

    public class SvitemCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new SvItem();
} protected override object GetElementKey(ConfigurationElement element)
{
SvItem e = (SvItem)element;
return e.Hostname;
} public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.AddRemoveClearMap; public void Add(SvItem item)
{
string key = item.Hostname;
if(BaseGet(key)!= null)
{
BaseRemove(key);
}
BaseAdd(item);
} public void Remove(string host)
{
BaseRemove(host);
} public SvItem Get(string host)
{
return (BaseGet(host) as SvItem);
}
}

自定义的配置集合类,当然要以 ConfigurationElementCollection 为基类。这个集合中的每个项,就是咱们上面刚定义的 SvItem 类,所以,在实现 CreateNewElement 方法时,直接返回一个新的对象实例即可。

GetElementKey 方法返回一个标识,作为某个项在集合中的key,这里我就用它的 Hostname属性作为key吧。

为了便于在类的外部操作,我公开了几个方法:

Add:向集合中添加元素,实现时可以调用基类的 BaseAdd 方法。

Remove:从集合中删除某元素。参数是作为元素key的Hostname属性值。

Get:根据Hostname属性的值获取元素实例。

根据实际需要,你可以自己编写更多的成员,比如按索引查找元素等。

接着,我们就要来写配置节了。

    public class CustServs: ConfigurationSection
{
[ConfigurationProperty("servers", IsDefaultCollection = true)]
public SvitemCollection Servers
{
get { return (SvitemCollection)this["servers"]; }
}
}

集合属性一般不需要赋值,而只是向其中添加元素,所以属性只有 get 访问器,没有编写 set 访问器。应用 ConfigurationProperty 特性时,设置了 IsDefaultCollection 属性为 true ,表示将使用默认的元素管理行为,即用 add 元素来添加,用remove元素来删除,用 clear 元素来清空集合。

刚刚上面定义 SvitemCollection 集合时,我重写了 CollectionType 属性。

   public override ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.AddRemoveClearMap;

如此这个集合就支持 add、remove、clear 三种操作。

下面,咱们来试试用,在代码中进行好配置后,保存到 app.config 文件中。

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustServs sect = config.GetSection("custserver") as CustServs;
if(sect == null)
{
sect = new CustServs();
config.Sections.Add("custserver", sect);
} SvItem item1 = new SvItem { Hostname = "CholPC", Port = };
SvItem item2 = new SvItem { Hostname = "JobPC", Port = };
SvItem item3 = new SvItem { Hostname = "TomPC", Port = };
sect.Servers.Add(item1);
sect.Servers.Add(item2);
sect.Servers.Add(item3); config.Save(ConfigurationSaveMode.Modified);

执行上面代码后,打开与应用程序同一目录下的 app.config 文件,就会看到生成这样的配置。

<configuration>
<configSections>
<section name="custserver" type="MyApp.CustServs, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<custserver>
<servers>
<add host="CholPC" port="3255" />
<add host="JobPC" port="2500" />
<add host="TomPC" port="566" />
</servers>
</custserver>

……
</configuration>

默认集合的行为是用add元素来添加项的。

然后,我们把刚刚 Servers 属性的代码改一下。

    public class CustServs: ConfigurationSection
{
[ConfigurationProperty("servers", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(SvitemCollection), AddItemName = "server", RemoveItemName = "del", ClearItemsName = "clr")]
public SvitemCollection Servers
{
get { return (SvitemCollection)this["servers"]; }
}
}

首先可以把 IsDefaultCollection 改为 false,接着应用 ConfigurationCollection 特性,注意传递给构造函数的 type 是我们定义的集合类的type。AddItemName、RemoveItemName、ClearItemsName 这三个属性是用于替换 add、remove、clear 这几个默认名。

修改后,再次执行代码,生成的配置文件如下。

<configuration>
<configSections>
<section name="custserver" type="MyApp.CustServs, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<custserver>
<servers>
<server host="CholPC" port="3255" />
<server host="JobPC" port="2500" />
<server host="TomPC" port="566" />
</servers>
</custserver>
……
</configuration>

这时候,你也发现了,向配置集合添加元素,不再使用 add 了,而是变为 server 了。

当然了,除了在代码中配置,你也可以直接在配置文件中设置,然后在代码中读取,这个与上一篇文章中所述的一样。

好了,该开饭了,本文内容就到此完结。

【.net 深呼吸】在配置节中使用元素集合的更多相关文章

  1. (转)通过在 Page 指令或 配置节中设置 validateRequest=false 可以禁用请求验证

    通过在 Page 指令或 配置节中设置 validateRequest=false 可以禁用请求验证 说明:   请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止.该值可能指示危及应用 ...

  2. 修改和获取web.config或app.config文件appSettings配置节中的Add里的value属性 函数

    1: /// <summary> 2: /// 修改web.config或app.config文件appSettings配置节中的Add里的value属性 3: /// </summ ...

  3. 创建在“system.net/defaultProxy”配置节中指定的Web代理时出错解决办法。

    出现这种问题会有很多原因,大致解决方法 方法1:在CMD下输入netsh winsock reset命令 简单来说netsh winsock reset命令含义是重置 Winsock 目录.如果一台机 ...

  4. 【.net 深呼吸】自定义应用程序配置节

    实际上,应用程序配置文件 App.config,是由各个节(Configuration Section)组成的,通常,配置节是按功能划分的,比如我们很熟悉的 appSettings.connectio ...

  5. 在 ServiceModel 客户端配置部分中,找不到引用协定“IpsBarcode.ScanService”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素中找不到与此协定匹配的终结点元素。

    一个类库引用了web service A,用另一个EXE做承载时,访问这个web service A时就提示:“在 ServiceModel 客户端配置部分中,找不到引用协定“IpsBarcode.S ...

  6. IIS7错误:不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的(overrideModeDefault="Deny")......

    不能在此路径中使用此配置节.如果在父级别上锁定了该节,便会出现这种情况.锁定是默认设置的(overrideModeDefault="Deny")...... 解决方案: 因为 II ...

  7. 在 ServiceModel 客户端配置部分中,找不到引用协定“WebServiceTest.WebServiceSoap”的默认终结点元素。这可能是因为未找到应用程序的配置文件,或者是因为客户端元素

    原文  http://blog.csdn.net/bugdemo/article/details/9083497 主题 技术 在引用WebService后,程序运行到实例化WebService时报错, ...

  8. IIS关于“ 配置错误 不能在此路径中使用此配置节”的解决办法

    IIS关于“ 配置错误 不能在此路径中使用此配置节”的解决办法 原文链接:http://www.cnblogs.com/200325074/p/3679316.html 今天刚安装好IIS8.5, 我 ...

  9. 在 ServiceModel 客户端配置部分中,找不到引用协定“PmWs.PmWebServiceSoap”的默认终结点元素

    System.Exception: ConfigManager.LoadConfigurationFromDb ServiceFactory.GetPmWebService 在 ServiceMode ...

随机推荐

  1. 【解决】使用compass watch xxx.scss 失败

    原始日期:2016-01-25 16:49 在上一篇博客,我们终于安装好了compass,不过紧接着使用compass watch app.scss 结果失败,经过查询资料,是compass的版本问题 ...

  2. Hadoop 笔记1 (原理和HDFS分布式搭建)

    1. hadoop 是什么 以及解决的问题 (自行百度) 2.基本概念的讲解 1. NodeName  master 节点(NN) 主节点 保存了metaData(元数据信息) 包括文件的owener ...

  3. 探索Windows命令行系列(3):命令行脚本基础

    1.实用功能 1.1.为脚本添加注释 1.2.控制命令的回显 1.3.使用数学表达式 1.4.向脚本传递参数 2.使用变量 2.1.变量的命名及定义 2.2.调用变量 2.3.变量的作用域 3.结构语 ...

  4. 基于Dubbo的分布式事务框架(LCN)

    原文地址:http://原文地址:https://github.com/1991wangliang/transaction 基于Dubbo的分布式事务框架(LCN) 该框架依赖Redis/dubbo/ ...

  5. 彩扩机项目--NPN和PNP三极管作为开关管的区别

    上图是最终画好的电路.使用的是NPN三极管,并且把NPN三极管放在了下面.下面分析下NPN三极管作为开关管能否放在上面. 从上面两张图分析可知,当三极管作为开关管使用的时候,NPN三极管需要放在下面( ...

  6. asp.net中怎样调用存储过程和存储过程的写法(转载,留着自己看)

    asp.net中怎样调用存储过程和存储过程的写法 创建一个只有输入参数的存储过程 create procedure proc_user@name varchar(20),@Password varch ...

  7. 外部世界如何访问容器? - 每天5分钟玩转 Docker 容器技术(37)

    上节我们学习了容器如何访问外部网络,今天讨论另一个方向:外部网络如何访问到容器? 答案是:端口映射. docker 可将容器对外提供服务的端口映射到 host 的某个端口,外网通过该端口访问容器.容器 ...

  8. 多表链接 Left join

    select * from( select  U_User.LinkMan, SP_Approval.* ,SP_Approval_Msg.ApprovalUserID,ROW_NUMBER()   ...

  9. SQL-结构化查询语言(1)

    一:数据查询语言(DQL),Data Query Language,用以从表中获取数据,确定数据怎样在程序中给出.SELECT是DQL中用的最多的! select user,host,password ...

  10. 虚函数&多态

    对于经常被问到的虚函数和多态的问题,发现百度百科回答得十分详细,所以自己在百度百科上的解释进行总结 一.虚函数 (1)虚函数简介:在某基类中声明为virtual并在一个或者多个派生类中被重新定义的成员 ...