前言

  之前接触到Redis,然后选用了对StackExchange.Redis又一层封装的StackExchange.Redis.Extensions.Core类库。阅读源代码的过程中发现了他使用Configuration实现读取自定义配置的方法。特此学习并记录。在我们日常开发中,最常用的自定义配置读取方式莫过于如下两种方式,尤其是连接数据库。

           //读取appsetting
var appSettingValue = ConfigurationManager.AppSettings["KEY"];
//读取connectionstring
var connectionValue = ConfigurationManager.ConnectionStrings["KEY"];

  而在使用这个类库的时候它的配置形式是这样的:

<configSections>
<section name="redisCacheClient"
type="StackExchange.Redis.Extensions.Core.Configuration.RedisCachingSectionHandler, StackExchange.Redis.Extensions.Core" />
</configSections> <redisCacheClient allowAdmin="true" ssl="false" connectTimeout="5000" database="0" password="">
<hosts>
<add host="127.0.0.1" cachePort="6379"/>
<add host="127.0.0.1" cachePort="6380"/>
  </hosts>
</redisCacheClient>

  没错,就是自定义section,然后在读取section中详细的配置信息,如上述代码所示,sectionName=redisCacheClient,allowAdmin,ssl等都是它的配置信息。<hosts>节点比较特殊,它是一系列配置信息的集合。

代码解读

  先看一下自定义配置接口,里面就包含了 redisCacheClient中的各种属性定义

  

/// <summary>
/// 自定义配置接口
/// </summary>
public interface IRedisCachingConfiguration
{
/// <summary>
/// Redis Server的服务端口配置
/// </summary>
/// <value>
/// IP地址或者服务器名称
/// </value>
RedisHostCollection RedisHosts { get; } /// <summary>
/// The strategy to use when executing server wide commands
/// </summary>
ServerEnumerationStrategy ServerEnumerationStrategy { get; } /// <summary>
/// 定义是否该连接可以使用管理员权限操作,比如flush database
/// </summary>
/// <value>
/// <c>true</c> 可以使用管理员权限; 否则, <c>false</c>.
/// </value>
bool AllowAdmin { get; } /// <summary>
/// 是否SSL安全加密
/// </summary>
/// <value>
/// <c>true</c> if is secure; otherwise, <c>false</c>.
/// </value>
bool Ssl { get; } /// <summary>
/// 连接超时时间
/// </summary>
int ConnectTimeout { get; } /// <summary>
/// 没有服务可用的时候,不会创建新连接
/// </summary>
bool AbortOnConnectFail { get; } /// <summary>
/// Database Id
/// </summary>
/// <value>
/// database的ID,默认为0
/// </value>
int Database { get; } /// <summary>
/// 密码
/// </summary>
string Password { get; }
}

  我们看一下类的具体实现,首先要继承自定义的接口,还要继承ConfigurationSection,这样当我们取比如说 allowAdmin的值的时候可以在内部直接调用 this["allowAdmin"]取到值了。

  /// <summary>
/// 继承自定义接口,并且继承ConfigurationSection<see cref="IRedisCachingConfiguration"/>
/// </summary>
public class RedisCachingSectionHandler : ConfigurationSection, IRedisCachingConfiguration
{ //这里就只拿allowAdmin举例,默认是string类型,那么我们就要根据自己的需求进行数据类型转换了。这里就把string类型转换为我们想要的bool类型
[ConfigurationProperty("allowAdmin")]
public bool AllowAdmin
{
get
{ bool result = false;
var config = this["allowAdmin"]; if (config != null)
{
var value = config.ToString(); if (!string.IsNullOrEmpty(value))
{
if (bool.TryParse(value, out result))
{
return result;
}
}
} return result;
}
} //其他代码
    ...
    ...
/// <summary>
/// 读取配置信息,外部调用主方法
/// </summary>
/// <returns></returns>
public static RedisCachingSectionHandler GetConfig()
{
return ConfigurationManager.GetSection("redisCacheClient") as RedisCachingSectionHandler;
}
}

  下面我们在看一下元素集合的使用,单节点RedisHost代码如下:

/// <summary>
/// RedisHost的配置元素
/// </summary>
public class RedisHost : ConfigurationElement
{
/// <summary>
/// Gets the Redis host.
/// </summary>
/// <value>
///获取host节点值
/// </value>
[ConfigurationProperty("host", IsRequired = true)]
public string Host
{
get
{
return this["host"] as string;
}
} /// <summary>
/// Gets the port.
/// </summary>
/// <value>
/// 获取cachePort的值
/// </value>
[ConfigurationProperty("cachePort", IsRequired = true)]
public int CachePort
{
get
{
var config = this["cachePort"];
if (config != null)
{
var value = config.ToString(); if (!string.IsNullOrEmpty(value))
{
int result; if (int.TryParse(value, out result))
{
return result;
}
}
} throw new Exception("Redis Cahe port must be number.");
}
}
}

  还需要定义一个Collection将Hosts中的内容收集起来。类似List

/// <summary>
/// Configuration Element Collection for <see cref="RedisHost"/>
/// </summary>
public class RedisHostCollection : ConfigurationElementCollection
{
/// <summary>
/// Gets or sets the <see cref="RedisHost"/> at the specified index.
/// </summary>
/// <value>
/// The <see cref="RedisHost"/>.
/// </value>
/// <param name="index">The index.</param>
/// <returns></returns>
public RedisHost this[int index]
{
//BaseGet,BaseRemoveAt,BaseAdd都是 ConfigurationElementCollection 中定义的方法
get
{
//调用BaseGet方法获取节点信息
return BaseGet(index) as RedisHost;
}
set
{
//设置的时候先删掉,在添加
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
} BaseAdd(index, value);
}
} /// <summary>
///此方法需要重写,返回一个新节点
/// </summary>
/// <returns></returns>
protected override ConfigurationElement CreateNewElement()
{
return new RedisHost();
} /// <summary>
/// 重写此方法,获取元素key
/// </summary>
/// <param name="element">元素</param>
/// <returns></returns>
protected override object GetElementKey(ConfigurationElement element)
//这里可以看到,这个key就是 Host:Port
=> $"{((RedisHost) element).Host}:{((RedisHost) element).CachePort}";
}

  经过一层层的包装之后,Handler中后去Host的节点方法就很简单了。

/// <summary>
/// The host of Redis Server
/// </summary>
/// <value>
/// The ip or name
/// </value>
[ConfigurationProperty("hosts")]
public RedisHostCollection RedisHosts
=> this["hosts"] as RedisHostCollection;

  我们运行程序读取一下试试:

         RedisCachingSectionHandler config = RedisCachingSectionHandler.GetConfig();
Console.WriteLine("config中的allowAdmin:" + config.AllowAdmin);
Console.WriteLine("config中的ssl:" + config.Ssl);
Console.WriteLine("config中的password:" + config.Password);
Console.WriteLine("config中的database:" + config.Database);
Console.WriteLine();
Console.WriteLine("读取Host信息如下:");
foreach (RedisHost host in config.RedisHosts)
{
Console.WriteLine($"{host.Host}:{host.CachePort}");
}
Console.Read();

  运行结果:

  

  config中的信息已经正常读取到。那么我们可以用这种方式实现读取自己自定义的配置信息啦。当然,简单的配置还是直接用 <add key="key" value="value"/>

总结

  微软库已经给我们提供了太多的方法,在不知情的情况下我们往往会自己去实现。多看看开源代码对自己知识的提升还有有帮助的。这不,学会了这种配置方法,我们就可使用不仅仅ConfigurationManager这个类了。

StackExchange.Redis.Extensions.Core 源码解读之 Configuration用法的更多相关文章

  1. spring core源码解读之ASM4用户手册翻译之一asm简介

    第一章:ASM介绍 1.1 ASM动机: 程序的分析,生成,转换技术可以应用到许多场景: 1.程序分析,从简单的语法解析到完整的语义分析,可以应用在程序中找到潜在的bug,发现无用的代码,工程代码的逆 ...

  2. asp.net core源码飘香:Configuration组件

    简介: 这是一个基础组件,是一个统一的配置模型,配置可以来源于配置文件(json文件,xml文件,ini文件),内存对象,命令行参数,系统的环境变量又或者是你自己扩展的配置源,该组件将各个配置源的数据 ...

  3. jvm源码解读--16 cas 用法解析

    CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...

  4. c# redis 操作类库推荐:StackExchange.Redis.Extensions

    StackExchange是一个优秀的c# redis客户端,但是存在操作略为繁琐的弊端,为了简化操作,使用 StackExchange.Redis.Extensions成为了一个非常值得推荐的选择. ...

  5. Jfinal-Plugin源码解读

    PS:cnxieyang@163.com/xieyang@e6yun.com 本文就Jfinal-plugin的源码进行分析和解读 Plugin继承及实现关系类图如下,常用的是Iplugin的三个集成 ...

  6. Jfinal启动源码解读

    本文对Jfinal的启动源码做解释说明. PS:Jfinal启动容器可基于Tomcat/Jetty等web容器启动,本文基于Jetty的启动方式做启动源码的解读和分析,tomcat类似. 入口  JF ...

  7. JFinal的启动源码解读

    本文对Jfinal的启动源码做解释说明. PS:Jfinal启动容器可基于Tomcat/Jetty等web容器启动,本文基于Jetty的启动方式做启动源码的解读和分析,tomcat类似. 入口  JF ...

  8. 《.NET 5.0 背锅案》第7集-大结局:捉拿真凶 StackExchange.Redis.Extensions 归案

    第1集:验证 .NET 5.0 正式版 docker 镜像问题 第2集:码中的小窟窿,背后的大坑,发现重要嫌犯 EnyimMemcachedCore 第3集-剧情反转:EnyimMemcachedCo ...

  9. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

随机推荐

  1. Karma Police - Radiohead

    音乐赏析似乎是一件没有意义的工作,与电影相比音乐更加抽象,不同的人对同一首歌会有完全不同的解读. 但一首歌一旦成为经典,就有解读它的必要,因为它一定诉出了一个群体的某些情绪. Karma police ...

  2. Linux 指令

    cat cdchmod chowncp cut 名称:cat使用权限:所有使用者使用方式:cat [-AbeEnstTuv] [--help] [--version] fileName说明:把档案串连 ...

  3. 基础知识复习(二)——stdafx.h 头文件及x&(x-1)运算

    今天好久没写过C++程序了,使用VS2013 新建空的控制台程序,结果自动生成了头文件和main 方法. 就了解了stdafx.h头文件的含义及用法. stdafx:standard Applicat ...

  4. C#导出csv文件 支持中文的解决方案

    #region 导出CSV下载 string exportFileName = "Export" + DateTime.Now.ToString("yyyyMMddHHm ...

  5. TCP && UDP

    TCP(Transmission Control Protocol,传输控制协议) 是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接. TCP建立连接要进行3次握手,而断开连接要进行 ...

  6. eclipse改变theme

    https://github.com/eclipse-color-theme/eclipse-color-theme.git https://github.com/eclipse-color-them ...

  7. Windows与Linux主机之间的连接和交互工具

    1.Putty 远程连接Linux主机 Windows主机上安装putty,工具打开后显示如下: 输入要连接的Linux主机的IP地址,点击Load,连接主机后输入用户名密码,即可登录Linux主机 ...

  8. 在standalone模式下运行yarn 0.9.0对HDFS上的数据进行计算

    1.通读http://spark.incubator.apache.org/docs/latest/spark-standalone.html 2.在每台机器上将spark安装到/opt/spark ...

  9. Windows Server 2003 Sp2 下无法安装SQL Server 2008 Management Studio Express问题

    Windows Server 2003 Sp2 下无法安装SQL Server 2008 Management Studio Express问题钉子 发表于 2010-5-22 1:42:51问题描述 ...

  10. 记录一些容易忘记的属性 -- UINavigationController

    //设置导航栏的风格    self.navigationController.navigationBar.barStyle = UIBarStyleDefault;    //设置导航栏是否透明 N ...