【.net 深呼吸】自定义应用程序配置节
实际上,应用程序配置文件 App.config,是由各个节(Configuration Section)组成的,通常,配置节是按功能划分的,比如我们很熟悉的 appSettings、connectionStrings、startup、system.ServiceModel……
在实际开发中,我们的应用程序也应该需要一个咱们程序专且功能的配置节,这样也方便我们在代码中通过相关的API来读取,而不是用普通的XML文件读取方法。
其实,实现自定义配置节并不难,只是,有几个问题要注意。
老周一边给大伙伴们演示一边讲解,这样会比较有情调。
要自定义应用配置节,必须从 ConfigurationSection 类派生,该类是个抽象类,所以我们必须以其作为基类来定义自己的配置节。虽然它是一个抽象类,但是,功能很完善,多数情况下,我们是不需要重写它的成员(特殊需求的话,可以按需重写),给大家演示一下,看看我这个类。
public class MyDemoSection : ConfigurationSection
{
……
}
那么,我们在这个类中要干啥呢?我们要给它添加我们需要的属性。比如,我需要两个属性——一个 User,字符串类型;另一个Age,类型为int。
public class MyDemoSection : ConfigurationSection
{
public string User
{
get {……}
set { ……}
} public int Age
{
get { ……}
set { …… }
}
}
这时候,你一定会想到一个问题:那配置文件API在保存到配置文件时,是如何识别的呢。其实这个 ConfigurationSection 类的基类是 ConfigurationElement。ConfigurationElement 是所有配置文件元素的共同基类。配置节实则就是一种特殊的配置元素,它与普通的配置元素的区别在于,配置节通常作为一类功能的主节点。而配置节的子元素就是普通的配置元素;配置节在使用前必须在 configSections 节点下进行声明,声明后才能在配置文件中使用。这个咱们后面再谈。
ConfigurationElement 类公开了以下两个版本的索引器:
protected internal object this[string propertyName] { get; set; }
protected internal object this[ConfigurationProperty prop] { get; set; }
我们一般用的是带string参数的版本,这个索引器只能在派生类中访问,不对外部公开。而 ConfigurationSection 类是从 ConfigurationElement 类派生的,自然会继承这个索引器。
所以,我们在自定义配置节的属性包装中,可以通过这个索引器来存取内容,其操作方法类似于字典。
public class MyDemoSection : ConfigurationSection
{
public string User
{
get { return (string)this["user"]; }
set { this["user"] = value; }
} public int Age
{
get { return (int)this["age"]; }
set { this["age"] = value; }
}
}
代码写到这里,貌似是完成了,其实未然。这时候,如果你想用代码把这个自定义节点写入配置文件,就会收到以下异常。

因为我们的自定义配置节类还没有完工,还差一个 Attribute 没有应用。应该这样写。
[ConfigurationProperty("user")]
public string User
{
get { return (string)this["user"]; }
set { this["user"] = value; }
}
[ConfigurationProperty("age")]
public int Age
{
get { return (int)this["age"]; }
set { this["age"] = value; }
}
注意,严重要注意!!应用的ConfigurationPropertyAttribute 中指定的name一定要和索引器(this["....."])中使用的名字相同,比如上面的代码,age要一致,如果改为这样,就会报错。
[ConfigurationProperty("number")]
public int Age
{
get { return (int)this["age"]; }
set { this["age"] = value; }
}
因为 number 和 age 不匹配,不过,类型的属性名不要求,比如,Age属性可以改为 Num。
[ConfigurationProperty("age")]
public int Num
{
get { return (int)this["age"]; }
set { this["age"] = value; }
}
把属性名改为 Num 是不会报错的。只要 ConfigurationPropertyAttribute 中的 name 参数与索引器中的名字一致即可。
下面,我们试试这个自定义配置节,我们通过代码来配置,然后保存到 App.Config 中。
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
MyDemoSection sect = new MyDemoSection();
config.Sections.Add("myInfo", sect);
//sect.SectionInformation.ForceSave = false;
sect.User = "Ben Dan";
sect.Age = ;
// 保存
config.Save(ConfigurationSaveMode.Modified);
通过....Sections.Add 方法就可以把自定义的配置节添加配置文件中,其中,有一个name 参数,它用来指定在使用该配置时的XML元素名称。这个你如果不理解,不急,你先记住我们代码中写的名字叫 myInfo。
然后执行一下上面的代码,再打开与应用程序相关的App.config文件,注意不是项目中的config文件,是bin\\ 目录下的。打开后你会看到这样的内容。
<configuration>
<configSections>
<section name="myInfo" type="CustConfigs.MyDemoSection, CaiDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<myInfo user="Ben Dan" age="25" />
……
</configuration>
怎么样,你现在看明白了没,知道那个 myInfo 怎么用了吧。
首先,要在 configSections 节中用 section 元素来配置一下自定义配置节的类型,type指定的就是我们刚刚定义的那个 MyDemoSection 类,其实只需要写上类型名和程序集名即可。name 指定一个名称,就是你随后在配置文件使用时的XML元素名,如本例中的 myInfo。
在上面的代码中,可能你注意到有一行代码被注释了,
sect.SectionInformation.ForceSave = false;
MSDN 上说,这个属性指示是否要强制保存配置节的内容,哪怕它没有被修改过,这里我用不上,就注释掉了,因为MSDN上的示例有这一行,我故意加上来装逼一下的。
刚才,我们通过代码应用我自定义配置节,内容已写入 app.config 文件,此时我们如果再次运行上面的代码,你会发现报错了。

原来配置节是不能重复 Add 的,所以我们改改代码,先进行判断。
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
MyDemoSection sect = config.Sections["myInfo"] as MyDemoSection;
if(sect == null)
{
sect = new MyDemoSection();
config.Sections.Add("myInfo", sect);
}
sect.User = "Ben Dan";
sect.Age = ;
// 保存
config.Save(ConfigurationSaveMode.Modified);
好了,这样可避免报错了。
接下来,老周再给各位举一例,这一次我们不用代码来写配置文件,而是直接编辑配置文件,然后在代码中读出配置信息。这种做法应该最常用。
还是那样,我们自定义一个配置节类型。
public class DBSection : ConfigurationSection
{
[ConfigurationProperty("dbName", DefaultValue = "db.mdf")]
public string DBName
{
get { return (string)this["dbName"]; }
set { this["dbName"] = value; }
} [ConfigurationProperty("loginName", DefaultValue = "sa")]
public string LoginName
{
get { return (string)this["loginName"]; }
set { this["loginName"] = value; }
}
}
假设,DBName 表示数据库文件的名字,LoginName表示登入 MSSQL 的名称(默认是 sa)。
然后,我们打开\bin\debug 下面的app.config,注意,不是项目中的配置文件。先为自定义配置节进行声明。
<configSections>
<section name="db" type="CustConfigs.DBSection, CaiDemo"/>
</configSections>
这时候,要配置的话,XML元素名为db。
<db dbName ="app.mdf" loginName="admin" />
注意这里设置的属性名不是类上的属性名,而是 ConfigurationPropertyAttribute 所指定的名称。
现在,我们在代码中读出这些配置参数。
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
DBSection sect = config.Sections["db"] as DBSection;
if (sect != null)
{
string s = $"数据库:{sect.DBName},登录名:{sect.LoginName}。";
Console.WriteLine(s);
}
注意刚刚我们在配置文件中声明时,给自定义节的元素命名为 db 。
<section name="db" type="CustConfigs.DBSection, CaiDemo"/>
所以,我们读的时候,也要用 db 作为名字取出配置节实例,然后再读属性的值。
最后,输出结果如下:

好了,今天的内容就扯到这里吧,这个玩意儿,大家学会之后,还是很有实战价值的,而且也不难。
【.net 深呼吸】自定义应用程序配置节的更多相关文章
- .Net 自定义应用程序配置
.Net 自定义应用程序配置 引言 几乎所有的应用程序都离不开配置,有时候我们会将配置信息存在数据库中(例如大家可能常会见到名为Config这样的表):更多时候,我们会将配置写在Web.config或 ...
- C#创建自定义配置节
在.Net应用程序中,我们经常看到VS为我们生成的项目工程中都会含有nfig或者nfig这样的文件.这个文件就是我们所说的应用程序配置文件.在这个文件里面记述着一些与我们的应用程序相关的信息,如:数据 ...
- C#如何使用和开发自定义配置节
在日常的程序设计中,如何灵活和巧妙地运用配置信息是一个成功的设计师的首要选择.这不仅是为了程序设计得更灵活性和可扩展性,也是为了让你的代码给人以清新的感觉.程序中的配置信息一般放在应用程序的app.c ...
- 【.net 深呼吸】在配置节中使用元素集合
前一篇博文中,老周介绍了自定义配置节的方法,本文咱们再往深一层,再看看如何在自定义的配置节中使用配置元素集合. 前面咱们说过,Configuration Section是特殊的配置元素,它可以包装一类 ...
- 在做了 BasePage 时: 只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态。还请确保在应用程序配置的 / / 节中包括
摘自: http://lichengguizy.blog.163.com/blog/static/11771858620122342749552/ 只有在配置文件或 Page 指令中将 enableS ...
- 使用 ConfigurationSection 创建自定义配置节
我们可以通过用自己的 XML 配置元素来扩展标准的 ASP.NET 配置设置集,要完成这一功能,我们必须实现继承System.Configuration.ConfigurationSection 类来 ...
- C# App.config 自定义 配置节
1)App.config <?xml version="1.0" encoding="utf-8" ?><configuration> ...
- asp.net web.config配置节说明
web.config 文件查找规则: (1)如果在当前页面所在目录下存在web.config文件,查看是否存在所要查找的结点名称,如果存在返回结果并停止查找. (2)如果当前页面所 ...
- asp.net web.config配置节说明(转发)
原文地址:http://www.cnblogs.com/qingyuan/articles/1501644.html web.config 文件查找规则: (1)如果在当前页面所在目录下存在 ...
随机推荐
- 浅谈Swift和OC的区别
前言 转眼Swift3都出来快一年了,从OC到Swift也经历了很多,所以对两者的一些使用区别也总结了一点,暂且记录下,权当自己的一个笔记. 当然其中一些区别可能大家都有耳闻,所以这里也会结合自身的一 ...
- Builder模式详解及其在Android开发中的应用
一.引言 在Android开发中,采用Builder模式的代码随处可见,比如说Android系统对话框AlertDialog的使用或者是Android中的通知栏(Notification)的使用,又比 ...
- MATLAB命令大全和矩阵操作大全
转载自: http://blog.csdn.net/dengjianqiang2011/article/details/8753807 MATLAB矩阵操作大全 一.矩阵的表示在MATLAB中创建矩阵 ...
- DOCKER 从入门到放弃(二)
搜索镜像 从docker官方镜像仓库搜索镜像 docker search [OPTIONS] TERM OPTIONS: --automated :只显示自动创建的镜像,默认值为fasle --fil ...
- Spring 学习一
Spring工作机制及为什么要用? 1.springmvc将所有的请求都提交给DispacherServlet,他会委托应用系统的其他模块负责对请求进行真正的处理工作. 2.DispacherServ ...
- SQL Server 文件结构 与 全局变量,函数
SQL Server 文件结构与全局变量 数据库和表 文件类型 主数据文件 .mdf 次要数据文件 .ndf 日志文件 .ldf 系统数据库 master 数据库 记录所有的登陆账户和系统配置设置 记 ...
- BootStrap dateRangePicker时间范围控件
BootStrap dateRangePicker时间范围控件 1 安装引用 1.1 下载zip Github:https://github.com/dangrossman/bootstrap-dat ...
- axis1.4开发webservice服务端(快速入门)-基于jdk1.4
写在前面: 现在有很多开发webservice的方法以及框架,什么cxf等,但是这些在你编写服务类的时候都要用到注解这个功能.如果现在的jdk是1.4的,那么就不能使用注解这个功能了.所以这里可以用到 ...
- H5 data-*容易忽略的问题
H5添加了data-*属性,非常方便 但经常忽略小写的问题, H5要求属性名全部小写,驼峰式命名的习惯掉坑了 测试代码如下: <html> <head> <script ...
- Spring源码:IOC原理解析(一)
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! IOC(Inversion of Control),即控制反转,意思是将对象的创建和依赖关系交给第三方容器处理,我们要用的时候告诉容器我们 ...