在 .NET中,一种更方便操作配置项的方法
在应用程序的开发过程中,我们往往会为软件提供一些配置项,以允许软件根据配置项灵活来做事情,比如配置日志文件路径等,此外,我们还可以用配置项来为用户存储其偏好设置等。
.NET 为我们默认提供了配置机制以及配置文件,项目中的 app.config 或者 web.config 文件(如果没有,可以添加)就是 .NET 为我们提供的配置文件。在这个配置文件中的根节点 configuration 下,创建 appSettings 节点,在此节点中,我们可以添加自定义的配置项。同时,ConfigurationManager 类提供了访问及操作此配置文件(由 Configuration 类代表)中配置的方法。需要注意的是,这个类在 System.Configuration.dll 文件中,需要将它添加到项目的引用中,才能使用。
本文主要介绍一种更为便利的方式来访问/存储配置项,当然,它本质上是使用 ConfigurationManager 类完成的。它主要的特点是以面向对象的方式来解决此问题,更具体地说,我们创建一个类,类中包括一些属性用以表示配置项,通过访问或设置这些属性,即可得到或更新对应的配置项。
一、实现
首先,我们为 Configuration 类添加一个扩展方法 AddOrUpdateAppSettingItem,如下 :
/// <summary>
/// 向配置的 AppSetings 节添加(如果不存在)或更新(如果已存在)给定的 key 和 value
/// </summary>
/// <param name="config"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public static void AddOrUpdateAppSettingItem(this Configuration config, string key, string value)
{
if (config.AppSettings.Settings.AllKeys.Contains(key))
{
config.AppSettings.Settings[key].Value = value;
}
else
{
config.AppSettings.Settings.Add(key, value);
}
}
}
这个方法主要实现了向 appSettings 节点添加(配置项不存在)或更新(配置项已存在)配置,接下来我们会用到这个方法。
接着,我们定义抽象基类 ConfigSetting,如下:
public abstract class ConfigSetting
{
/// <summary>
/// 配置类
/// </summary>
/// <param name="configuration">配置</param>
public ConfigSetting(Configuration configuration)
{
Configuration = configuration;
} /// <summary>
/// 当前配置
/// </summary>
public Configuration Configuration
{
get;
} /// <summary>
/// 获取当前程序配置
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static Configuration GetCurrentConfiguration()
{
return ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
} /// <summary>
/// 返回指定的配置项的值
/// </summary>
/// <param name="settingKey"></param>
/// <returns></returns>
protected virtual string GetSettingValue([CallerMemberName] string settingKey = null)
{
return Configuration?.AppSettings?.Settings[settingKey]?.Value;
} /// <summary>
/// 返回指定的配置项的值
/// </summary>
/// <typeparam name="T">值类型</typeparam>
/// <param name="settingKey"></param>
/// <returns></returns>
protected virtual T GetSettingValue<T>([CallerMemberName] string settingKey = null)
{
var value = GetSettingValue(settingKey); if (string.IsNullOrWhiteSpace(value))
{
return default(T);
}
else
{
return (T)Convert.ChangeType(value, typeof(T));
}
} /// <summary>
/// 为指定的配置项设置值
/// </summary>
/// <param name="value"></param>
/// <param name="settingKey"></param>
protected virtual void SetSettingValue(object value, [CallerMemberName] string settingKey = null)
{
Configuration.AddOrUpdateAppSettingItem(settingKey, value?.ToString());
Configuration.Save();
}
}
其中主要包括了一个静态方法和三个受保护的 virtual 方法,说明:
1. 静态方法 GetCurrentConfiguration 返回当前应用的配置类;
2. GetSettingValue 和 SetSettingValue 方法则分别负责读取、设置指定配置项的值;
3. GetSettingValue 有两个重载,其中一个用于支持泛型;
4. 在它们的方法签名中包括 CallerMemberName 特性,通过这个属性可以得到调用此访问的方法或属性的名称。
然后,创建一个名为 AppConfigSetting 的类,这个类将会包括一些代表配置项的属性,并且它要继承自 ConfigSetting,如下:
public class AppConfigSetting : ConfigSetting
{
public AppConfigSetting(Configuration configuration) : base(configuration)
{ } public DateTime InstallDateTime
{
get { return GetSettingValue<DateTime>(); }
set { SetSettingValue(value); }
} public string LogFileName
{
get { return GetSettingValue(); }
set { SetSettingValue(value); }
} public int ReadBlockSize
{
get { return GetSettingValue<int>(); }
set { SetSettingValue(value); }
}
}
说明:
1. 可以看到我们在其中增加了三个属性。而在它们的 get 与 set 段中,调用了基类中的对应的两个方法,其中,对于非 string 类型的配置项,我们调用的是 GetSettingValue<T>。
2. 通过我们前面提到的 CallerMemberName 特性,就可以得到这里的属性名,并得到相应的配置项,这样我们就无需硬编码。所以,这个属性名,本质上就是配置项的名称。
这样,我们将所有要用到的配置项作为属性放到 AppConfigSetting 类中,再用操作这些属性就可以完成所有对配置项的操作了。
二、如何使用
使用它,也非常简单,代码如下:
var config = ConfigSetting.GetCurrentConfiguration();
AppConfigSetting setting = new AppConfigSetting(config); // 未设置时
MessageBox.Show($"LogFileName: {setting.LogFileName}"); // 设置后,再读取
setting.LogFileName = "log.txt";
MessageBox.Show($"LogFileName: {setting.LogFileName}");
三、补充
为了满足在不向 AppConfigSetting 添加配置项属性,但却又要访问/存储指定配置项的需要,我们可以在基类 ConfigSetting 中添加以下三个方法:
/// <summary>
/// 返回指定的配置项的值
/// </summary>
/// <param name="settingKey"></param>
/// <returns></returns>
public string GetSettingValueByKey(string settingKey)
{
return GetSettingValue(settingKey);
} /// <summary>
/// 返回指定的配置项的值
/// </summary>
/// <param name="settingKey"></param>
/// <returns></returns>
public T GetSettingValueByKey<T>(string settingKey)
{
return GetSettingValue<T>(settingKey);
} /// <summary>
/// 为指定的配置项设置值
/// </summary>
/// <param name="value"></param>
/// <param name="settingKey"></param>
public void SetSettingValueByKey(string settingKey, object value)
{
SetSettingValue(value, settingKey);
}
使用这几个方法,可以自由地访问/存储配置项,不同于上面增加属性方式的是,它需要自己传递配置项 key 作参数。
使用:
// 未设置时
MessageBox.Show($"LogLevel: {setting.GetSettingValueByKey("LogLevel")}"); // 设置后,再读取
setting.SetSettingValueByKey("LogLevel", );
MessageBox.Show($"LogLevel: {setting.GetSettingValueByKey("LogLevel")}");
总结
本文主要介绍了一种访问应用程序配置更为便利的方式,其主要思想是通过基类中 GetSettingValue/SetSettingValue 两个方法借助于 CallerMemberName 特性而得到派生类中属性的名称而操作对应的配置项。当然,这里不仅提供了一种方法,更是提供一种思路,基于此,你还可以根据实际需要来调整、扩展以满足你的实际需要。
在 .NET中,一种更方便操作配置项的方法的更多相关文章
- Java中几种常用数据类型之间转换的方法
Java中几种常用的数据类型之间转换方法: 1. short-->int 转换 exp: short shortvar=0; int intvar=0; shortvar= (short) in ...
- [转]分享php中四种webservice实现的简单架构方法及实例
FROM : http://www.itokit.com/2012/0417/73615_2.html 本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的P ...
- 分享php中四种webservice实现的简单架构方法及实例
一:PHP本身的SOAP所有的webservice都包括服务端(server)和客户端(client).要使用php本身的soap首先要把该拓展安装好并且启用.下面看具体的code首先这是服务端实现: ...
- 分享php中四种webservice实现的简单架构方法及实例(转)
本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的PHPRPC,以及使用二进制传输数据流的 HessianPHP,那么一下就简单的介绍下这几种webserv ...
- 分享php中四种webservice实现的简单架构方法及实例[转载]
[转载]http://www.itokit.com/2012/0417/73615.html 本人所了解的webservice有以下几种:PHP本身的SOAP,开源的NUSOAP,商业版的PHPRPC ...
- JAVA中3种将byte转换为String的方法
HttpClient 类库中GetMethod类的getResponseBody方法返回的是byte[]类型,要操作起来不方便,我想把它转化成String类型. 查了网上的资料,有说法认为用这种方法比 ...
- lua中,两种json和table互转方法的效率比较
lua中json和table的互转,是我们在平时开发过程中经常用到的.比如: 在用lua编写的服务器中,如果客户端发送json格式的数据,那么在lua处理业务逻辑的时候,必然需要转换成lua自己的数据 ...
- 第9.10节 Python中IO模块其他文件操作属性和方法简介
本文中所有案例中的fp都是使用open函数打开文件返回的一个文件对象,为了节省篇幅,大部分没有提供文件打开的代码. 一. 文件是否关闭的属性 属性名:closed 功用:判断文件是否关闭 示例: &g ...
- 在Linux中三种让crontab每秒执行任务的方法
第一种方法: 1.创建脚本文件 cat phplog.sh 2.编辑脚本内容 #!/bin/bash while : ;do /home/scripts.sh 2>/dev/null & ...
随机推荐
- [C#]使用Quartz.NET来创建定时工作任务
本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.0及以 ...
- 关于git的一些理论知识
一.什么是版本控制器 好多刚用git的coder一说起git,就随口会说出版本控制器嘛,我问那是干嘛的,大部分人就回答上传代码的.然后会用,但是有些理论你问他们他们就不知道了,比如不是代码的文件就不能 ...
- lesson - 4 笔记 /inode / suid / sgid / sbit / chmod /umask / chown / rwx / wc /grep / tr / sort / cut /which / whereis / locate / find / ln /
一.帮助+基本文件管理+用户管理 1.怎么查看命令帮助 ls --help man ls :查看命令/man 5 file:查看配置文件 二.基本文件管理,通过{查,建,删,改} 四个维度介绍了不同的 ...
- Python 项目实践三(Web应用程序)第二篇
接着上节的继续学习,使用Django创建网页的过程通常分三个阶段:定义URL.编写视图和编写模板.首先,你必须定义URL模式,每个URL都被映射到特定的视图--视图函数获取并处理网页所需的数据.视图函 ...
- php中const与define的区别
1 版本差异: const 要求php的版本>5.3.0 define 可以兼容php4,php5 等版本 2 定义的位置区别: const关键字定义的常量是在编译时定义的,因此const关键字 ...
- ORA-00600[17059]错误
ORA-00600[17059] ORA-00600[17059]错误大部分都是因为高版本导致,对于本库的分析:因为该库的 shared pool老化比较频繁,到我介入的时候,发现相关该类此sql已经 ...
- sql优化原则与技巧
加快sql查询是非常重要的技巧,简单来说加快sql查询的方式有以下几种:一.索引的引用 1.索引一般可以加速数据的检索速度,加速表与表之间的链接,提高性能,所以在对海量数据进行处理时,考虑到信息量比较 ...
- Tableau的简单数据可视化操作
本文将讲解Tableau的基本使用和简单的数据分析. 在Tableau首页,我们可以看到有多种连接方式:文本文件.Excel.JSON文件.数据库等. 1.连接文本文件 点击"连接" ...
- Pandas库的使用--Series
一.概念 Series相当于一维数组. 1.调用Series的原生方法创建 import pandas as pd s1 = pd.Series(data=[1,2,4,6,7],index=['a' ...
- chrome调试工具高级不完整使用指南(优化篇)
上一篇文章我们说了chrome调试工具的一些比较基础功能的用法,接下来我们要在这一篇文章中说一说,其他一些chrome调试工具的使用方法 2.1.5 Network模块 在netWork模块中,大致上 ...