自定义配置项解析
对现有的配置节进行扩展,使配置项拥有更丰富的选项,此时需要使用配置项解析类来帮忙。配置项解析类的作用是解析配置节节点的数据,生成对应的配置项实例。
下面以分布式缓存 Redis 的实现为例,介绍如何解析自定义配置项。
首先我们知道,要使用 Redis,必须配置 Redis 的主机地址、密码、默认db等等一大堆参数,你的做法可能是将它们放到 appSettings (.Net Framework) 或 appsettings.json 的某一个节点下(.Net Core)。但是使用 Fireasy 的配置,你可以在对应的配置项中进行扩展。
1、定义配置文件
我们设定 Redis 配置的主要要素为:主机地址、密码、默认db,那么在原有的配置文件基础上进行如下的改造,即在原有的配置节点下增加子节点 config,如下所示:
- .Net Framework 下的 app.config 或 web.config 文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="fireasy">
<section name="cachings" type="Fireasy.Common.Caching.Configuration.CachingConfigurationSectionHandler, Fireasy.Common" />
</sectionGroup>
</configSections>
<fireasy>
<cachings>
<caching type="demo.RedisCacheManager, demo">
<config defaultDb="2" host="localhost">
</config>
</caching>
</cachings>
</fireasy>
</configuration>
- .Net Core 下的 appsettings.json 文件
{
"fireasy": {
"cachings": {
"settings": {
"redis": {
"type": "demo.RedisCacheManager, demo",
"config": {
"defaultDb": 2,
"host": "localhost"
}
}
}
}
}
}
2、建立 Redis 配置类
参照配置文件中的结构,为 Redis 建立其特有的配置类 RedisConfigurationSetting
,结构如下所示:
/// <summary>
/// Redis 的基本配置。
/// </summary>
[ConfigurationSettingParseType(typeof(RedisConfigurationSettingParser))]
public class RedisConfigurationSetting : IConfigurationSettingItem
{
/// <summary>
/// 获取 Redis 主机地址。
/// </summary>
public string Host { get; private set; }
/// <summary>
/// 获取或设置缺省的数据库编号。
/// </summary>
public int DefaultDb { get; set; }
/// <summary>
/// 获取或设置密码。
/// </summary>
public string Password { get; set; }
}
3、解析配置
RedisConfigurationSetting
类使用了 ConfigurationSettingParseTypeAttribute
特性进行了标记,它指定了使用 RedisConfigurationSettingParser
类来解析配置项。这个类实现了 IConfigurationSettingParseHandler
接口,两个 Parse 方法分别针对 .Net Framework 的 Xml
配置文件和 .Net Core 的 IConfiguration
进行解析。如下所示:
/// <summary>
/// Redis 配置的解析处理器。
/// </summary>
public class RedisConfigurationSettingParser : IConfigurationSettingParseHandler
{
public IConfigurationSettingItem Parse(System.Xml.XmlNode section)
{
var setting = new RedisConfigurationSetting();
var configNode = section.SelectSingleNode("config");
if (configNode != null)
{
setting.Host = configNode.GetAttributeValue<string>("host");
setting.DefaultDb = configNode.GetAttributeValue("defaultDb", 0);
setting.Password = configNode.GetAttributeValue("password");
}
return setting;
}
#if NETSTANDARD
public IConfigurationSettingItem Parse(IConfiguration configuration)
{
var setting = new RedisConfigurationSetting();
var configNode = configuration.GetSection("config");
if (configNode.Exists())
{
setting.Host = configNode["host"].To<string>();
setting.DefaultDb = configNode["defaultDb"].To(0);
setting.Password = configNode["password"];
}
return setting;
}
#endif
}
4、附加配置项
配置文件中,type 是一个 ICacheManager
接口的实现类 RedisCacheManager
,它需要做以下两件事情:
实现
IConfigurationSettingHostService
接口,以便管理器能够调用 Attach 方法将配置项传递给该实现类。使用
ConfigurationSettingAttribute
特性标记该实现类所使用的配置项类。
有了配置项后,你就可以连接到 Redis 服务器了,实现 Redis 分布式缓存,主要的代码如下所示:
[ConfigurationSetting(typeof(RedisConfigurationSetting))]
public class RedisCacheManager : IConfigurationSettingHostService
{
private RedisConfigurationSetting _setting;
void IConfigurationSettingHostService.Attach(IConfigurationSettingItem setting)
{
_setting = (RedisConfigurationSetting)setting;
//初始化 Redis 连接
}
}
注意初始化 Reids 连接不能在构造函数里处理,而应该放到 Attach 方法接收到配置项后再处理。