通过Cache机制实现通用的配置管理模块
.Net Web应用程序提供了很强大的 Web.Config功能,我们很多的系统可能已经习惯在Web.Config中进行配置,可是使用Web.Config进行一些配置,会有一些不太顺畅的特性,比如:修改Web.Config 后,Web应用程序会出现错误页面并且需要重新登录,Web.Config配置过程不是很方便,即使通过安装包进行Web.Config的设置,.Net 安装向导能提供的入口也是有限的。。。。。
通过Cache机制实现一个通用的配置管理模块
设计目标:
1、 高速读取配置信息
2、 统一的配置维护管理方便进行配置
3、 新的配置模块及维护不需要再进行二次开发
大致设计思路
1、 通过Cache机制对配置文件的内容进行缓存,缓存的失效依赖于配置文件
2、 在开发基础组件库中实现一个 CacheHelper 类统一读取配置信息
3、 根据配置文件自动生成配置维护界面,实现统一的配置维护
代码参考:
CacheHelper.cs 统一读取配置信息的一个类, 打开配置文件,读取相关的配置信息到HashTable ,并保存到 Cache中,Cache中存在则直接取Cache中的内容,否则重新读取文件,这样做到高速读取。
EpowerConfigHelper.cs
using System;
using System.Collections;
using System.Web;
using System.Web.Caching;
using System.Xml;
namespace Epower.DevBase.BaseTools
{
///
/// ConfigHelper 的摘要说明。
/// 自定义的系统参数配置文件的读取工具类
///
public class ConfigHelper
{
///
/// 取~/Config/CommonConfig.xml中某个参数名对应的参数值
///
/// 参数名
/// 参数值
public static string GetParameterValue(string ParameterName)
{
return GetParameterValue("EpowerConfig", ParameterName);
}
///
/// 取某个参数配置文件中某个参数名对应的参数值
/// 参数配置文件
/// 1、必须存放于"~/Config/"目录下面,以.xml为后缀
/// 2、配置格式参见~/Config/CommonConfig.xml
///
/// 配置文件的文件名,不要后缀
/// 参数名
/// 参数值
public static string GetParameterValue(string ConfigName, string ParameterName)
{
Hashtable CommonConfig = GetConfigCache(ConfigName);
if (CommonConfig.ContainsKey(ParameterName))
return CommonConfig[ParameterName].ToString();
else
throw new Exception("参数(" + ParameterName + ")没有定义,请检查配置文件!");
}
///
/// 将配置的参数转换成Hashtable并存入缓存,配置文件修改后自动更新缓存
///
///
///
private static Hashtable GetConfigCache(string ConfigName)
{
string CacheName = "Config_" + ConfigName;
Hashtable CommonConfig = new Hashtable();
Cache cache = HttpRuntime.Cache;
if (cache[CacheName] == null)
{
string ConfigPath = null;
#region 取应用程序根物理路径
try
{
ConfigPath = HttpRuntime.AppDomainAppPath;
}
catch (System.ArgumentException ex)
{
}
if (ConfigPath == null) throw new Exception("系统异常,取不到应用程序所在根物理路径!");
#endregion
string ConfigFile = ConfigPath + "Config\\" + ConfigName + ".xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(ConfigFile);
XmlNode oNode = xmlDoc.DocumentElement;
if (oNode.HasChildNodes)
{
XmlNodeList oList = oNode.ChildNodes;
for (int i = 0; i < oList.Count; i++)
{
CommonConfig.Add(oList[i].Attributes["Name"].Value, oList[i].Attributes["Value"].Value);
}
}
cache.Insert(CacheName, CommonConfig, new CacheDependency(ConfigFile));
}
else
CommonConfig = (Hashtable) cache[CacheName];
return CommonConfig;
}
}
}
using System;
using System.Collections;
using System.Web;
using System.Web.Caching;
using System.Xml;
namespace Epower.DevBase.BaseTools
{
///
/// ConfigHelper 的摘要说明。
/// 自定义的系统参数配置文件的读取工具类
///
public class ConfigHelper
{
///
/// 取~/Config/CommonConfig.xml中某个参数名对应的参数值
///
/// 参数名
///
public static string GetParameterValue(string ParameterName)
{
return GetParameterValue("EpowerConfig", ParameterName);
}
///
/// 取某个参数配置文件中某个参数名对应的参数值
/// 参数配置文件
/// 1、必须存放于"~/Config/"目录下面,以.xml为后缀
/// 2、配置格式参见~/Config/CommonConfig.xml
///
/// 配置文件的文件名,不要后缀
/// 参数名
///
public static string GetParameterValue(string ConfigName, string ParameterName)
{
Hashtable CommonConfig = GetConfigCache(ConfigName);
if (CommonConfig.ContainsKey(ParameterName))
return CommonConfig[ParameterName].ToString();
else
throw new Exception("参数(" + ParameterName + ")没有定义,请检查配置文件!");
}
///
/// 将配置的参数转换成Hashtable并存入缓存,配置文件修改后自动更新缓存
///
///
///
private static Hashtable GetConfigCache(string ConfigName)
{
string CacheName = "Config_" + ConfigName;
Hashtable CommonConfig = new Hashtable();
Cache cache = HttpRuntime.Cache;
if (cache[CacheName] == null)
{
string ConfigPath = null;
#region 取应用程序根物理路径
try
{
ConfigPath = HttpRuntime.AppDomainAppPath;
}
catch (System.ArgumentException ex)
{
}
if (ConfigPath == null) throw new Exception("系统异常,取不到应用程序所在根物理路径!");
#endregion
string ConfigFile = ConfigPath + "Config\\" + ConfigName + ".xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(ConfigFile);
XmlNode oNode = xmlDoc.DocumentElement;
if (oNode.HasChildNodes)
{
XmlNodeList oList = oNode.ChildNodes;
for (int i = 0; i < oList.Count; i++)
{
CommonConfig.Add(oList[i].Attributes["Name"].Value, oList[i].Attributes["Value"].Value);
}
}
cache.Insert(CacheName, CommonConfig, new CacheDependency(ConfigFile));
}
else
CommonConfig = (Hashtable) cache[CacheName];
return CommonConfig;
}
}
}
代码参考:
frmConfigSet.aspx 以配置文件名为参数,根据配置文件自动生成维护界面,并进行维护,保存。
根据配置动态加载控件
HtmlTable tab = new HtmlTable();
tab.ID = "tDynamic";
tab.Attributes.Add("width", "80%");
tab.Attributes.Add("class", "tablebody");
HtmlTableRow tr = new HtmlTableRow();
HtmlTableCell tc = new HtmlTableCell();
XmlNodeList nodes = xmldoc.DocumentElement.SelectNodes("Item");
string sConfigContent = "";
if (xmldoc.DocumentElement.Attributes["ConfigContent"] != null)
sConfigContent = xmldoc.DocumentElement.Attributes["ConfigContent"].Value;
string sItemDesc = "";
int iRow = 0;
foreach (XmlNode node in nodes)
{
iRow++;
tr = new HtmlTableRow();
tr.ID = "tDynamicRow" + iRow;
AddControlByNode(node,iRow,ref tr);
AddControl(tab, tr);
sItemDesc = "";
if (node.Attributes["ItemContent"] != null)
sItemDesc = node.Attributes["ItemContent"].Value;
if (sItemDesc.Length > 0)
{
//添加描述行
iRow++;
tr = new HtmlTableRow();
tr.ID = "tDyContectRow" + iRow;
tc = new HtmlTableCell();
tc.ID = "tDyContectTD_" + iRow;
tc.InnerText = sItemDesc;
tc.Attributes.Add("class", "list");
tc.Attributes.Add("colspan", "2");
AddControl(tr, tc);
AddControl(tab, tr);
}
}
HtmlTable tab = new HtmlTable();
tab.ID = "tDynamic";
tab.Attributes.Add("width", "80%");
tab.Attributes.Add("class", "tablebody");
HtmlTableRow tr = new HtmlTableRow();
HtmlTableCell tc = new HtmlTableCell();
XmlNodeList nodes = xmldoc.DocumentElement.SelectNodes("Item");
string sConfigContent = "";
if (xmldoc.DocumentElement.Attributes["ConfigContent"] != null)
sConfigContent = xmldoc.DocumentElement.Attributes["ConfigContent"].Value;
string sItemDesc = "";
int iRow = 0;
foreach (XmlNode node in nodes)
{
iRow++;
tr = new HtmlTableRow();
tr.ID = "tDynamicRow" + iRow;
AddControlByNode(node,iRow,ref tr);
AddControl(tab, tr);
sItemDesc = "";
if (node.Attributes["ItemContent"] != null)
sItemDesc = node.Attributes["ItemContent"].Value;
if (sItemDesc.Length > 0)
{
//添加描述行
iRow++;
tr = new HtmlTableRow();
tr.ID = "tDyContectRow" + iRow;
tc = new HtmlTableCell();
tc.ID = "tDyContectTD_" + iRow;
tc.InnerText = sItemDesc;
tc.Attributes.Add("class", "list");
tc.Attributes.Add("colspan", "2");
AddControl(tr, tc);
AddControl(tab, tr);
}
}
增加控件的代码段
///
/// 获取设置的控件
///
///
///
private Control GetSettingControl(XmlNode node)
{
string strCtrlType = node.Attributes["ControlType"].Value;
string strValue = node.Attributes["Value"].Value;
Control control;
switch (strCtrlType.ToLower())
{
case "text":
control = new TextBox();
control.ID = "tDynamic" + "_txt_" + node.Attributes["Name"].Value;
((TextBox)control).Width = new Unit("70%");
((TextBox)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
((TextBox)control).Text = strValue;
break;
case "checkbox":
control = new CheckBox();
control.ID = "tDynamic" + "_chk_" + node.Attributes["Name"].Value;
((CheckBox)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
((CheckBox)control).Text = node.Attributes["Desc"].Value;
if (strValue.ToLower() == "false")
{
((CheckBox)control).Checked = false;
}
else
{
((CheckBox)control).Checked = true;
}
break;
case "droplist":
control = new DropDownList();
control.ID = "tDynamic" + "_drp_" + node.Attributes["Name"].Value;
((DropDownList)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
((DropDownList)control).Width = new Unit("70%");
string[] sItems = node.Attributes["Dict"].Value.Split(",".ToCharArray());
for (int i = 0; i < sItems.Length; i++)
{
string[] arr = sItems[i].Split("|".ToCharArray());
((DropDownList)control).Items.Add(new ListItem(arr[1], arr[0]));
}
((DropDownList)control).SelectedValue = strValue;
break;
case "datetime":
control = (Epower.ITSM.Web.Controls.CtrDateAndTime)LoadControl("~/controls/ctrdateandtime.ascx");
((Epower.ITSM.Web.Controls.CtrDateAndTime)control).ShowTime = false;
control.ID = "tDynamic" + "_date_" + node.Attributes["Name"].Value;
((Epower.ITSM.Web.Controls.CtrDateAndTime)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
break;
default:
control = null;
break;
}
return control;
}
///
/// 获取设置的控件
///
///
///
private Control GetSettingControl(XmlNode node)
{
string strCtrlType = node.Attributes["ControlType"].Value;
string strValue = node.Attributes["Value"].Value;
Control control;
switch (strCtrlType.ToLower())
{
case "text":
control = new TextBox();
control.ID = "tDynamic" + "_txt_" + node.Attributes["Name"].Value;
((TextBox)control).Width = new Unit("70%");
((TextBox)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
((TextBox)control).Text = strValue;
break;
case "checkbox":
control = new CheckBox();
control.ID = "tDynamic" + "_chk_" + node.Attributes["Name"].Value;
((CheckBox)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
((CheckBox)control).Text = node.Attributes["Desc"].Value;
if (strValue.ToLower() == "false")
{
((CheckBox)control).Checked = false;
}
else
{
((CheckBox)control).Checked = true;
}
break;
case "droplist":
control = new DropDownList();
control.ID = "tDynamic" + "_drp_" + node.Attributes["Name"].Value;
((DropDownList)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
((DropDownList)control).Width = new Unit("70%");
string[] sItems = node.Attributes["Dict"].Value.Split(",".ToCharArray());
for (int i = 0; i < sItems.Length; i++)
{
string[] arr = sItems[i].Split("|".ToCharArray());
((DropDownList)control).Items.Add(new ListItem(arr[1], arr[0]));
}
((DropDownList)control).SelectedValue = strValue;
break;
case "datetime":
control = (Epower.ITSM.Web.Controls.CtrDateAndTime)LoadControl("~/controls/ctrdateandtime.ascx");
((Epower.ITSM.Web.Controls.CtrDateAndTime)control).ShowTime = false;
control.ID = "tDynamic" + "_date_" + node.Attributes["Name"].Value;
((Epower.ITSM.Web.Controls.CtrDateAndTime)control).Attributes.Add("Tag", node.Attributes["Name"].Value);
break;
default:
control = null;
break;
}
return control;
}
配置文件范例:
Xml Config范例
xml version="1.0" encoding="utf-8"?>
<EmailConfig Title="邮件服务设置" ConfigContent="邮件服务器设置,服务器设置,.服务器设置,.服务器设置,.服务器设置,.服务器设置,.服务器设置,.">
<Item Name="smtpserver" Value="smtp.vip.sina.com" Desc="邮件SMTP服务器" ControlType="TEXT" ItemContent="设置邮件SMTP服务器的地址,格式:smtp.vip.sina.com">
Item>
<Item Name="smtpfrom" Value="[email protected]" Desc="邮件地址" ControlType="TEXT" ValidationExpression="^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$">
Item>
<Item Name="smtpUserName" Value="cancankf" Desc="帐户" ControlType="TEXT">
Item>
<Item Name="smtppsd" Value="123456" Desc="密码" ControlType="TEXT">
Item>
<Item Name="smtpSSL" Value="false" Desc="是否SSL" ControlType="CHECKBOX">
Item>
<Item Name="smtpPort" Value="0" Desc="端口" ControlType="TEXT" ValidationExpression="\d{0,9}">
Item>
<Item Name="smtpDateTest" Value="2008-07-21" Desc="测试日期" ControlType="DATETIME">
Item>
<Item Name="smtpListTest" Value="0" Desc="测试列表" ControlType="DROPLIST" Dict="0|值1,1|值2,2|值3">
Item>
EmailConfig>
xml version="1.0" encoding="utf-8"?>
<EmailConfig Title="邮件服务设置" ConfigContent="邮件服务器设置,服务器设置,.服务器设置,.服务器设置,.服务器设置,.服务器设置,.服务器设置,.">
<Item Name="smtpserver" Value="smtp.vip.sina.com" Desc="邮件SMTP服务器" ControlType="TEXT" ItemContent="设置邮件SMTP服务器的地址,格式:smtp.vip.sina.com">
Item>
<Item Name="smtpfrom" Value="[email protected]" Desc="邮件地址" ControlType="TEXT" ValidationExpression="^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$">
Item>
<Item Name="smtpUserName" Value="cancankf" Desc="帐户" ControlType="TEXT">
Item>
<Item Name="smtppsd" Value="123456" Desc="密码" ControlType="TEXT">
Item>
<Item Name="smtpSSL" Value="false" Desc="是否SSL" ControlType="CHECKBOX">
Item>
<Item Name="smtpPort" Value="0" Desc="端口" ControlType="TEXT" ValidationExpression="\d{0,9}">
Item>
<Item Name="smtpDateTest" Value="2008-07-21" Desc="测试日期" ControlType="DATETIME">
Item>
<Item Name="smtpListTest" Value="0" Desc="测试列表" ControlType="DROPLIST" Dict="0|值1,1|值2,2|值3">
Item>
EmailConfig>
读取配置信息范例
Code
string sSmtpServer = ConfigHelper.GetParameterValue("EmailConfig","smtpserver");
string sSmtpServer = ConfigHelper.GetParameterValue("EmailConfig","smtpserver");
E8.Net开源架构提供了这一功能的全部代码。用户可以直接使用或参考,并在此基础上更加的完善。
E8.Net 工作流架构大量节约用户的开发成本为企业应用开发提供起点,提升软件生产力,欢迎访问: http://***/productFlow.htm