ASP.NET MVC 学习笔记-7.自定义配置信息(后续)
自定义配置信息的高级应用
通过上篇博文对简单的自定义配置信息的学习,使得更加灵活的控制系统配置信息。实际项目中,这种配置的灵活度往往无法满足项目的灵活度和扩展性。
比如,一个配置信息有三部分组成,而每部分中有包括一些配置信息。仅仅使用简单的自定义配置无法满足,因此,需要提供更多的自定义配置方法来灵活实现。
针对配置信息中包括配置列表和配置项的要求,主要使用.Net Framework中的以下两个类来实现:
ConfigurationElement:配置文件中的一个配置项
ConfigurationElementCollection:配置文件中的一个配置项集合
ConfigurationSection:配置文件中的一个配置节信息。
使用下面的表格能够更好说明三者之间的关系:
|
ConfigurationSection |
||
|
1:N |
ConfigurationElementCollection |
|
|
1:N |
ConfigurationElement <add …/> |
|
|
ConfigurationElement <add …/> |
||
|
ConfigurationElement <add …/> |
||
针对以上知识点,使用一个项目实例逐渐展开。
项目需求:
库位管理系统需要实现仓库的全方位展示,设计多种数据(SQLserver、Oracle、MySQL等),每个数据库连接字符串的加密方式存在无法统一的情况。
配置文件的规划:
针对以上需求,对数据库配置文件信息的规划为:
|
DBConnectionConfiguration(ConfigurationSection) |
|||||||||||
|
ConnectionStrings(ConfigurationElementCollection) |
|||||||||||
|
ConnectionString1(ConfigurationElement) |
|||||||||||
|
name |
description |
connectionString |
providerName |
connectionDecryptName |
|||||||
|
ConnectionString2(ConfigurationElement) |
|||||||||||
|
name |
description |
connectionString |
providerName |
connectionDecryptName |
|||||||
|
DataProviders(ConfigurationElementCollection) |
|||||||||||
|
DataProvider1(ConfigurationElement) |
|||||||||||
|
name |
description |
type |
|||||||||
|
DataProvider2(ConfigurationElement) |
|||||||||||
|
name |
description |
type |
|||||||||
|
ConnectionDecrypts(ConfigurationElementCollection) |
|||||||||||
|
ConnectionDecrypt(ConfigurationElement) |
|||||||||||
|
name |
description |
type |
|||||||||
|
ConnectionDecrypt(ConfigurationElement) |
|||||||||||
|
name |
description |
type |
|||||||||
配置信息实体的定义:
针对以上配置信息,先对配置信息对应的实体进行设计:
1. DBConnectionConfiguration类
它作为配置文件中的一个配置节存在,配置节名称定义为TT.connectionManager,需要继承自ConfigurationSection类,同时,它还需要定义三个属性,分别是ConnectionStrings、DataProviders、ConnectionDecrypts,这三个属性都是列表信息,因此是ConfigurationElementCollection的自定义子类。
/// <summary>
/// 数据库连接配置信息
/// </summary>
public class DBConnectionConfiguration : ConfigurationSection
{
private const string SECION_NAME = "TT.connectionManager"; /// <summary>
/// 获取数据库连接配置信息
/// </summary>
public static DBConnectionConfiguration GetConfig()
{
var config = ConfigurationManager.GetSection(SECION_NAME) as DBConnectionConfiguration;
return config;
} /// <summary>
/// 数据库连接字符串配置集合
/// </summary>
[ConfigurationProperty("connectionStrings")]
public ConnectionStringCollection ConnectionStrings
{
get
{
return (ConnectionStringCollection)base["connectionStrings"];
}
} /// <summary>
/// DataProvider配置集合
/// </summary>
[ConfigurationProperty("dataProviders", IsRequired = true)]
public DataProviderCollection DataProviders
{
get
{
return (DataProviderCollection)base["dataProviders"];
}
} /// <summary>
/// 连接字符串加密方式
/// </summary>
[ConfigurationProperty("connectionDecrypts", IsRequired = false)]
public ConnectionDecryptCollection ConnectionDecrypts
{
get
{
return (ConnectionDecryptCollection)base["connectionDecrypts"];
}
}
}
2. ConnectionString类
由于定义ConfigurationElementCollection的子类时,需要使用泛型方式,定义其包含的配置项的类型,因此,先定义配置项的实体。
由于,三个不同的配置项派生类都需要在配置信息中定义名称和描述信息来标识配置项信息,因此,提取出配置项基类,使用的配置项实体都继承自该基类,不同的配置信息在各自类中进行自定义。
/// <summary>
/// 以名字为键值的配置项
/// </summary>
public class NamedConfigurationElement : ConfigurationElement
{
/// <summary>
/// 名称
/// </summary>
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public virtual string Name
{
get
{
return (string)this["name"];
}
} /// <summary>
/// 描述
/// </summary>
[ConfigurationProperty("description", DefaultValue = "")]
public virtual string Description
{
get
{
return (string)this["description"];
}
}
}
以ConnectionStringElement为例,该实体定义三个属性信息:数据库连接字符串信息、数据库访问提供者、连接加密信息名称,其中连接加密名称填写时,使用ConnectionDecryptCollection中的定义解密类的类型信息进行反射实例化进行解密,不填写时则直接使用连接字符串信息。
/// <summary>
/// 连接字符串配置项
/// </summary>
public class ConnectionStringElement:NamedConfigurationElement
{
/// <summary>
/// 连接字符串
/// </summary>
private string _connectionString = ""; /// <summary>
/// 连接字符串
/// </summary>
[ConfigurationProperty("connectionString")]
public string ConnectionString
{
get
{
if (!string.IsNullOrWhiteSpace(_connectionString))
return _connectionString;
var decryptName = ConnectionDecryptName;
if (string.IsNullOrWhiteSpace(decryptName))
_connectionString = (string)base["connectionString"];
else
{
DBConnectionConfiguration config = DBConnectionConfiguration.GetConfig();
var decrytType = config.ConnectionDecrypts[decryptName].Type;
IConnectionDecrypt cb = ReflectionHelper.CreateInstance(decrytType) as IConnectionDecrypt;
_connectionString = cb.Decrypt((string)base["connectionString"]);
}
return _connectionString;
}
} /// <summary>
/// DataProvider名称
/// </summary>
[ConfigurationProperty("providerName")]
public string ProviderName
{
get
{
return (string)base["providerName"];
}
} /// <summary>
/// 连接字符串加密方法名称
/// </summary>
[ConfigurationProperty("connectionDecryptName", DefaultValue = "", IsRequired = false)]
public string ConnectionDecryptName
{
get
{
return (string)base["connectionDecryptName"];
}
}
}
/// <summary>
/// DataProvider配置项
/// </summary>
public class DataProviderElement: NamedConfigurationElement
{
/// <summary>
/// DataProvider类型信息
/// </summary>
[ConfigurationProperty("type")]
public string Type
{
get
{
return (string)base["type"];
}
}
}
/// <summary>
/// 字符串加密方式配置项
/// </summary>
public class ConnectionDecryptElement:NamedConfigurationElement
{
/// <summary>
/// 字符串加密方式类型信息
/// </summary>
[ConfigurationProperty("type")]
public string Type
{
get
{
return (string)base["type"];
}
}
}
3. ConnectionStrings类
ConnectionStrings、DataProviders、ConnectionDecrypts三个配置列表实体,都会使用到使用配置项的名称获取对应的配置信息,因此需要将公共方法提取出来基类。
public abstract class NamedConfigurationElementCollection<T> : ConfigurationElementCollection
where T : NamedConfigurationElement, new()
{
/// <summary>
/// 按照名称获取指定的配置元素
/// </summary>
/// <param name="name">名称</param>
/// <returns>配置元素</returns>
public new T this[string name] { get { return (T)BaseGet(name); } }
/// <summary>
/// 是否包含指定的配置元素
/// </summary>
/// <param name="name">配置元素名称</param>
/// <returns>是否包含</returns>
public bool ContainsKey(string name) { return BaseGet(name) != null; }
/// <summary>
/// 添加元素
/// </summary>
/// <param name="obj"></param>
public virtual void Add(T obj)
{
BaseAdd(obj);
}
/// <summary>
/// 得到元素的Key值
/// </summary>
/// <param name="element">配置元素</param>
/// <returns>配置元素所对应的配置元素</returns>
protected override object GetElementKey(ConfigurationElement element) { return ((T)element).Name; }
/// <summary>
/// 生成新的配置元素实例
/// </summary>
/// <returns>配置元素实例</returns>
protected override ConfigurationElement CreateNewElement() { return new T(); }
}
定义基类后,ConnectionStrings、DataProviders、ConnectionDecrypts三个配置列表实体只需要继承该基类,不需要任何实现。
public class ConnectionStringCollection: NamedConfigurationElementCollection<ConnectionStringElement>
{ } public class DataProviderCollection: NamedConfigurationElementCollection<DataProviderElement>
{ } public class ConnectionDecryptCollection: NamedConfigurationElementCollection<ConnectionDecryptElement>
{ }
通过以上配置实体类的定义,就可以使用以下方式获取到数据库配置信息:
DBConnectionConfiguration settings = DBConnectionConfiguration.GetConfig();
然后,根据数据库连接的名称获取到对应的信息,比如:
var connectionString = settings.ConnectionStrings[dbName].ConnectionString;
这里的DBName就是connectString配置项中的name信息。
ASP.NET MVC 学习笔记-7.自定义配置信息(后续)的更多相关文章
- ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...
- ASP.NET MVC 学习笔记-7.自定义配置信息
ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, <appSettings> <add key="LogInf ...
- ASP.NET MVC学习笔记-----使用自定义的View Engine
我们都知道在ASP.NET MVC中自带了Razor View Engine,Razor十分的强大,可以满足我们绝大部分的需要.但是ASP.NET MVC的高度可扩展性,使我们可以使用自定义的View ...
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
ASP.NET MVC 学习笔记-2.Razor语法 1. 表达式 表达式必须跟在“@”符号之后, 2. 代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...
- ASP.NET MVC学习笔记-----Filter2
ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...
- ASP.NET MVC学习笔记-----Filter
ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...
- ASP.NET MVC学习笔记-----Filter(2)
接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用,它需要实现IActionFilter接口: public ...
- ASP.NET MVC学习笔记-----ControllerFactory
上面这张图是asp.net mvc的工作流程图,我们可以看到当一个http请求来临时,首先需要经过路由系统,路由系统从中获取一些路由信息,然后ControllerFactory根据所得到的路由信息生成 ...
- ASP.NET MVC学习笔记-----ActionInvoker
还是这张图: 当ControllerFactory生成Controller实例后,这时就需要使用ActionInvoker来选择调用一个合适的Action执行.ASP.NET MVC提供的基类Cont ...
随机推荐
- 功能强大的js数组方法:reduce
arr.reduce()方法接受一个函数作为累加器,数组中的每个值从左到右开始缩减,最终为一个值. reduce接受的参数主要有callback(回调函数)和可选参数initvalue(作为第一次调用 ...
- 如何高效地写CSS--等以后有空多加总结一下
CSS写的并不多,如果从零开始的项目,自己一定想搬砖来得容易点.CSS编写一定有其工程化的方法,来时编写更加有效率. 考虑将CSS的预处理LESS.Sass或Stylus引入,或者将CSS的后处理Po ...
- Node.js 开发指南
1.Node.js 简介 Node.js 其实就是借助谷歌的 V8 引擎,将桌面端的 js 带到了服务器端,它的出现我将其归结为两点: V8 引擎的出色: js 异步 io 与事件驱动给服务器带来极高 ...
- SSAS 内部错误:操作未能成功
错误 -1056964601 : 内部错误: 操作未能成功,已终止. HY0008 是数据源的问题,设置数据源的虚拟连接就可以了
- 2018年1月20日上海MVP线下技术分享会纪实
1月20日正值大寒节气,在微软MVP朱兴亮的组织牵头下,上海MVP自发举办了题为<跟社区专家一起聊聊混合云.领域驱动.区块链和数字营销>的技术交流会.四名来自上海的MVP分别在自己擅长的技 ...
- VSCode插件开发全攻略(十)打包、发布、升级
更多文章请戳VSCode插件开发全攻略系列目录导航. 发布方式 插件开发完了,如何发布出去分享给他人呢?主要有3种方法: 方法一:直接把文件夹发给别人,让别人找到vscode的插件存放目录并放进去,然 ...
- Open-Source Cybersecurity Infrastructure
https://www.linkedin.com/pulse/open-source-cybersecurity-infrastructure-adrian/ The increased maturi ...
- pip 安装模块时出现error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools":
在使用pip安装mysqlclient模块时,出现如下错误: 在网上查找资料后显示可能是由于不兼容导致的,最好去下载.whl文件安装成功. 资源地址:http://www.lfd.uci.edu/~g ...
- 一线互联网常见的14个Java面试题,你颤抖了吗程序员
跳槽不算频繁,但参加过不少面试(电话面试.face to face面试),面过大/小公司.互联网/传统软件公司,面糊过(眼高手低,缺乏实战经验,挂掉),也面过人,所幸未因失败而气馁,在此过程中不断查缺 ...
- 如果这样来理解HTTPS,一篇就够了!
1.前言 可能有初学者会问,即时通讯应用的通信安全,不就是对Socket长连接进行SSL/TLS加密这些知识吗,干吗要理解HTTPS协议呢. 这其实是个误解:当今主流的移动端IM数据通信,总结下来无外 ...