目前流行的asp.net架构很多,有开源的有模式与实践(Microsoft patterns & practices)小组的开源项目Web Service Factory,Nhibernet, Nbear ORM, Petshop等架构; 下面我又介绍另一种基于元数据(XML)架构,在ASP.net2.0的程 序应用,而且这种架构目前很多 IT公司使 用较少,它的特点灵活度较高, 简单高效,方便的IOC依赖注入,对象 间解偶性好,开发效率较高,可以结合微软企业库进行 高效率的存储。 我在微软互联星空项目中,微软有很好的成功案例。
总体思想是采用XML(Template模板)进行权限控制,参考下图:
首先在Global.asax设置全局对象,系统启动后会把相关持久对象装入内存,提高系统运行速度:
相关代码如下:
<%@ Application Language="C#" %>
<%@ Import Namespace="Microsoft.XXXXX.Advertising.SystemFrameWork" %>
<%@ Import Namespace="Microsoft.XXXXX.Advertising.SystemFrameWork" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
SystemVM VM = new SystemVM();
Application.Lock();
Application["VM"] = VM;
Application.UnLock();
}
void Application_End(object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码
{
SystemVM VM = new SystemVM();
Application.Lock();
Application["VM"] = VM;
Application.UnLock();
}
void Application_End(object sender, EventArgs e)
{
// 在应用程序关闭时运行的代码
}
void Application_Error(object sender, EventArgs e)
{
// 在出现未处理的错误时运行的代码
void Application_Error(object sender, EventArgs e)
{
// 在出现未处理的错误时运行的代码
}
void Session_Start(object sender, EventArgs e)
{
// 在新会话启动时运行的代码
{
// 在新会话启动时运行的代码
}
void Session_End(object sender, EventArgs e)
{
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。
{
// 在会话结束时运行的代码。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer
// 或 SQLServer,则不会引发该事件。
}
</script>
</script>
第二,建立SystemVM.cs驱动模型类,包括一些相关属性和装载相关Template模板:
部分逻辑流程如下:
简略代码如下:
public class SystemVM
{
//角色模板
private SystemService m_system = null;
private OrderService m_order = null;
private QueryService m_query = null;
private FoundationService m_found = null;
/// <summary>
///
/// </summary>
public XmlNode XmlDimension
{
get
{
if (HttpContext.Current.Cache["dimension"] == null)
{
LoadXmlDimension();
}
return (XmlNode)HttpContext.Current.Cache["dimension"];
}
}
/// <summary>
/// 查询模板
/// </summary>
public XmlNode XmlQueryList
{
get
{
if (HttpContext.Current.Cache["querylist"] == null)
{
LoadXmlQueryList();
}
return (XmlNode)HttpContext.Current.Cache["querylist"];
}
}
///
/// </summary>
public XmlNode XmlDimension
{
get
{
if (HttpContext.Current.Cache["dimension"] == null)
{
LoadXmlDimension();
}
return (XmlNode)HttpContext.Current.Cache["dimension"];
}
}
/// <summary>
/// 查询模板
/// </summary>
public XmlNode XmlQueryList
{
get
{
if (HttpContext.Current.Cache["querylist"] == null)
{
LoadXmlQueryList();
}
return (XmlNode)HttpContext.Current.Cache["querylist"];
}
}
/// <summary>
/// JavaScript模板
/// </summary>
public XmlNode XmlJavaScript
{
get
{
if (HttpContext.Current.Cache["javascript"] == null)
{
LoadXmlJavaScript();
}
return (XmlNode)HttpContext.Current.Cache["javascript"];
}
}
/// <summary>
/// 省分模板
/// </summary>
public XmlNode XmlProvince
{
get
{
if (HttpContext.Current.Cache["province"] == null)
{
LoadXmlProvince();
}
return (XmlNode)HttpContext.Current.Cache["province"];
}
}
#region 多角色模板
/// <summary>
/// 系统角色模板
/// </summary>
public XmlNode XmlTemplate
{
get
{
XmlNode xmlNode = null;
if (HttpContext.Current.Request.Cookies["user"] != null)
{
string sWebSiteType = HttpContext.Current.Request.Cookies["user"]["WebSiteType"];
/// JavaScript模板
/// </summary>
public XmlNode XmlJavaScript
{
get
{
if (HttpContext.Current.Cache["javascript"] == null)
{
LoadXmlJavaScript();
}
return (XmlNode)HttpContext.Current.Cache["javascript"];
}
}
/// <summary>
/// 省分模板
/// </summary>
public XmlNode XmlProvince
{
get
{
if (HttpContext.Current.Cache["province"] == null)
{
LoadXmlProvince();
}
return (XmlNode)HttpContext.Current.Cache["province"];
}
}
#region 多角色模板
/// <summary>
/// 系统角色模板
/// </summary>
public XmlNode XmlTemplate
{
get
{
XmlNode xmlNode = null;
if (HttpContext.Current.Request.Cookies["user"] != null)
{
string sWebSiteType = HttpContext.Current.Request.Cookies["user"]["WebSiteType"];
if (sWebSiteType == "0")
{
xmlNode = XmlCenterTemplate;
}
if (sWebSiteType == "1")
{
xmlNode = XmlProvinceTemplate;
}
if (sWebSiteType == "2")
{
xmlNode = XmlCityTemplate;
}
{
xmlNode = XmlCenterTemplate;
}
if (sWebSiteType == "1")
{
xmlNode = XmlProvinceTemplate;
}
if (sWebSiteType == "2")
{
xmlNode = XmlCityTemplate;
}
}
return xmlNode;
}
}
return xmlNode;
}
}
public XmlNode XmlCenterTemplate
{
get
{
if (HttpContext.Current.Cache["CenterTemplate"] == null)
{
LoadXmlCenterTemplate();
}
return (XmlNode)HttpContext.Current.Cache["CenterTemplate"];
}
}
public XmlNode XmlProvinceTemplate
{
get
{
if (HttpContext.Current.Cache["ProvinceTemplate"] == null)
{
LoadXmlProvinceTemplate();
}
return (XmlNode)HttpContext.Current.Cache["ProvinceTemplate"];
}
}
public XmlNode XmlCityTemplate
{
get
{
if (HttpContext.Current.Cache["CityTemplate"] == null)
{
LoadXmlCityTemplate();
}
return (XmlNode)HttpContext.Current.Cache["CityTemplate"];
}
}
/// <summary>
/// 加栽角色权限模板
/// </summary>
private void LoadXmlCenterTemplate()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "CenterTemplate.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("CenterTemplate", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlProvinceTemplate()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "ProvinceTemplate.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("ProvinceTemplate", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlCityTemplate()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "CityCenterTemplate.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("CityTemplate", doc.DocumentElement,
new CacheDependency(sPath));
}
#endregion
/// <summary>
/// 系统服务
/// </summary>
public SystemService SystemService
{
get
{
return m_system;
}
}
/// <summary>
/// 查询服务
/// </summary>
public QueryService QueryService
{
get
{
return m_query;
}
}
/// <summary>
/// 基础信息
/// </summary>
public FoundationService FoundationService
{
get
{
return m_found;
}
}
/// <summary>
/// 订单管理
/// </summary>
public OrderService OrderService
{
get
{
return m_order;
}
}
public SystemVM()
{
LoadBusinessObj();
}
/// <summary>
/// 根据模板类型,返回系统可以选择的模板种类。
/// </summary>
/// <param name="sType"></param>
/// <returns></returns>
public XmlNodeList GetXmlJavaScriptByType(string sType)
{
XmlNodeList xmlNodeList = XmlJavaScript.SelectNodes("//项[@类型='" + sType + "']");
if (xmlNodeList.Count<0)
{
throw new Exception("找不到类型为["+sType+"]的节点!");
}
return xmlNodeList;
}
/// <summary>
/// 根据模板名称,获取JavaScript模板
/// </summary>
/// <param name="sName"></param>
/// <returns></returns>
public string GetXmlJavaScriptTpl(string sName)
{
StringBuilder sJsTemplate = new StringBuilder("");
XmlNode xmlNode = XmlJavaScript.SelectSingleNode("//项[@名称='" + sName + "']");
if (xmlNode == null)
{
throw new Exception("找不到名称为[" + sName + "]的节点!");
}
string sPath = ToolFunc.GetXmlString(xmlNode, "@模版");
sPath = AppDomain.CurrentDomain.BaseDirectory + sPath;
using (TextReader sr = File.OpenText(sPath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sJsTemplate.AppendLine(line);
}
}
return sJsTemplate.ToString();
}
public string GetUrlFromJavaScript(string sName)
{
string sUrl = "#";
XmlNode xmlNode = XmlJavaScript.SelectSingleNode("//项[@名称='" + sName + "']");
if (xmlNode == null)
{
throw new Exception("找不到名称为[" + sName + "]的节点!");
}
XmlElement el = (XmlElement)xmlNode;
sUrl = el.GetAttribute("Url");
return sUrl;
}
private void LoadXmlProvince()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "Province.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("province", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlJavaScript()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "JavaScript.Config";
doc.Load(sPath);
HttpContext.Current.Cache.Insert("javascript", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlDimension()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "Dimension.Config";
doc.Load(sPath);
HttpContext.Current.Cache.Insert("dimension", doc.DocumentElement,
new CacheDependency(sPath));
}
/// <summary>
///
/// </summary>
private void LoadXmlQueryList()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "QueryList.config";
doc.Load(sPath);
HttpContext.Current.Cache.Insert("querylist", doc.DocumentElement,
new CacheDependency(sPath));
}
{
get
{
if (HttpContext.Current.Cache["CenterTemplate"] == null)
{
LoadXmlCenterTemplate();
}
return (XmlNode)HttpContext.Current.Cache["CenterTemplate"];
}
}
public XmlNode XmlProvinceTemplate
{
get
{
if (HttpContext.Current.Cache["ProvinceTemplate"] == null)
{
LoadXmlProvinceTemplate();
}
return (XmlNode)HttpContext.Current.Cache["ProvinceTemplate"];
}
}
public XmlNode XmlCityTemplate
{
get
{
if (HttpContext.Current.Cache["CityTemplate"] == null)
{
LoadXmlCityTemplate();
}
return (XmlNode)HttpContext.Current.Cache["CityTemplate"];
}
}
/// <summary>
/// 加栽角色权限模板
/// </summary>
private void LoadXmlCenterTemplate()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "CenterTemplate.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("CenterTemplate", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlProvinceTemplate()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "ProvinceTemplate.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("ProvinceTemplate", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlCityTemplate()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "CityCenterTemplate.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("CityTemplate", doc.DocumentElement,
new CacheDependency(sPath));
}
#endregion
/// <summary>
/// 系统服务
/// </summary>
public SystemService SystemService
{
get
{
return m_system;
}
}
/// <summary>
/// 查询服务
/// </summary>
public QueryService QueryService
{
get
{
return m_query;
}
}
/// <summary>
/// 基础信息
/// </summary>
public FoundationService FoundationService
{
get
{
return m_found;
}
}
/// <summary>
/// 订单管理
/// </summary>
public OrderService OrderService
{
get
{
return m_order;
}
}
public SystemVM()
{
LoadBusinessObj();
}
/// <summary>
/// 根据模板类型,返回系统可以选择的模板种类。
/// </summary>
/// <param name="sType"></param>
/// <returns></returns>
public XmlNodeList GetXmlJavaScriptByType(string sType)
{
XmlNodeList xmlNodeList = XmlJavaScript.SelectNodes("//项[@类型='" + sType + "']");
if (xmlNodeList.Count<0)
{
throw new Exception("找不到类型为["+sType+"]的节点!");
}
return xmlNodeList;
}
/// <summary>
/// 根据模板名称,获取JavaScript模板
/// </summary>
/// <param name="sName"></param>
/// <returns></returns>
public string GetXmlJavaScriptTpl(string sName)
{
StringBuilder sJsTemplate = new StringBuilder("");
XmlNode xmlNode = XmlJavaScript.SelectSingleNode("//项[@名称='" + sName + "']");
if (xmlNode == null)
{
throw new Exception("找不到名称为[" + sName + "]的节点!");
}
string sPath = ToolFunc.GetXmlString(xmlNode, "@模版");
sPath = AppDomain.CurrentDomain.BaseDirectory + sPath;
using (TextReader sr = File.OpenText(sPath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sJsTemplate.AppendLine(line);
}
}
return sJsTemplate.ToString();
}
public string GetUrlFromJavaScript(string sName)
{
string sUrl = "#";
XmlNode xmlNode = XmlJavaScript.SelectSingleNode("//项[@名称='" + sName + "']");
if (xmlNode == null)
{
throw new Exception("找不到名称为[" + sName + "]的节点!");
}
XmlElement el = (XmlElement)xmlNode;
sUrl = el.GetAttribute("Url");
return sUrl;
}
private void LoadXmlProvince()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "Province.Config";
doc.Load(sPath);
XmlNode xmlNode = doc.DocumentElement;
HttpContext.Current.Cache.Insert("province", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlJavaScript()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "JavaScript.Config";
doc.Load(sPath);
HttpContext.Current.Cache.Insert("javascript", doc.DocumentElement,
new CacheDependency(sPath));
}
private void LoadXmlDimension()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "Dimension.Config";
doc.Load(sPath);
HttpContext.Current.Cache.Insert("dimension", doc.DocumentElement,
new CacheDependency(sPath));
}
/// <summary>
///
/// </summary>
private void LoadXmlQueryList()
{
string strBasePath = AppDomain.CurrentDomain.BaseDirectory;
XmlDocument doc = new XmlDocument();
string sPath = strBasePath + @"Template\" + "QueryList.config";
doc.Load(sPath);
HttpContext.Current.Cache.Insert("querylist", doc.DocumentElement,
new CacheDependency(sPath));
}
/// <summary>
/// 加载业务对象
/// </summary>
private void LoadBusinessObj()
{
m_system = new SystemService(this);
m_order = new OrderService(this);
m_found = new FoundationService(this);
m_query = new QueryService(this);
}
/// 加载业务对象
/// </summary>
private void LoadBusinessObj()
{
m_system = new SystemService(this);
m_order = new OrderService(this);
m_found = new FoundationService(this);
m_query = new QueryService(this);
}
此时可以根据数据库的角色记录,通过元数据模型进行权限与模板匹配,从而达到非常棒的架构设计。