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 ...
随机推荐
- Debian 8下手工安装 Eclipse CDT neon.2
从 http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neon2 下载 eclipse-cpp-neon-2-li ...
- 论文word排版相关插件
其中包括破解版的MathType.EndNote X7以及Aurora 链接:http://pan.baidu.com/s/1boRZTmf 密码:a6ai
- 可参数化的带优先级的数据选择器的FPGA实现方式探讨
在FPGA设计中,大部分情况下我们都得使用到数据选择器.并且为了设计参数化,可调,通常情况下我们需要一个参数可调的数据选择器,比如M选1,M是可调的参数. 如果,数据选择器是不带优先级的,我们可以使用 ...
- 在ASP.NET Core MVC中构建简单 Web Api
Getting Started 在 ASP.NET Core MVC 框架中,ASP.NET 团队为我们提供了一整套的用于构建一个 Web 中的各种部分所需的套件,那么有些时候我们只需要做一个简单的 ...
- 【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权
[.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我们介绍了网关使用Redis进行缓存,并介绍了如何进行缓存实现,缓存信息清理接口的使用.本篇我们将介绍如何实现网关自定义客户端授权, ...
- Linux pwn入门教程(10)——针对函数重定位流程的几种攻击
作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解 ...
- Spring Boot 的 10 个核心模块
学习 Spring Boot 必须得了解它的核心模块,和 Spring 框架一样,Spring Boot 也是一个庞大的项目,也是由许多核心子模块组成的. 你所需具备的基础 告诉你,Spring Bo ...
- socket 实现单一串口共享读写操作
前提:物理串口连接到PC上,通过串口号被PC唯一识别. 此时,物理串口通过该串口号仅能被单一线程或进程实例并占用,其他线程或进程不能再通过该串口号与物理串口通信.这个暂称为串口独占性. 解决思路:核心 ...
- Python 中的object takes no parameters错误
Python是一门面向对象的语言,中我们首先创建一个类: class Student(object): def _init_(self,name,score): self.name = name se ...
- ORM基本操作回顾
连接数据库 默认是MySQLdb 指定引擎 dialect[+driver]: //user:password@host/dbname[?key=value..]: from sqlalchemy i ...