PetShop的结构
表现层:PetShop.Web.CategoryDataProxy
public static CategoryInfo GetCategory(string categoryId) {
Category category = new Category();
if (!enableCaching)//页面层判断缓存逻辑
return category.GetCategory(categoryId);
string key = "category_" + categoryId;//使用缓存
CategoryInfo data = (CategoryInfo)HttpRuntime.Cache[key];
// Check if the data exists in the data cache
if (data == null) {
// If the data is not in the cache then fetch the data from the business logic tier
data = category.GetCategory(categoryId);
// Create a AggregateCacheDependency object from the factory
AggregateCacheDependency cd = DependencyFacade.GetCategoryDependency();
// Store the output in the data cache, and Add the necessary AggregateCacheDependency object
HttpRuntime.Cache.Add(key, data, cd, DateTime.Now.AddHours(categoryTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
}
return data;
}
业务层:(以Category类0为例)
BLL项目(常规表数据业务)和Profile项目(个性化信息资料的业务)
业务层可以调用实体类层和数据接口层
using PetShop.Model;
using PetShop.IDAL;
private static readonly ICategory dal = PetShop.DALFactory.DataAccess.CreateCategory();//工厂方法生成静态实例缓存 实现接口【见备注1】
public IList<CategoryInfo> GetCategories() {
return dal.GetCategories();
}
public CategoryInfo GetCategory(string categoryId) {
// Validate input业务层要做输入验证
if (string.IsNullOrEmpty(categoryId))
return null;
// Use the dal to search by category Id
return dal.GetCategory(categoryId);
}
数据层:
一、数据工厂:
DALFactory项目和ProfileDALFactory项目(作为业务层实例化的替代方式)
二、接口层:IDAL项目和IProfileDAL项目【见备注2】
分别作为表数据访问和普通数据访问的接口
三、数据访问层【见备注3】
PetShop.SQLServerDAL.Category : Icategory(继承接口层 PetShop.IDAL.Icategory CategoryInfo GetCategory(string categoryId);)
public CategoryInfo GetCategory(string categoryId) {
//Set up a return value
CategoryInfo category = null;
//Create a parameter
SqlParameter parm = new SqlParameter(PARM_CATEGORY_ID, SqlDbType.VarChar, 10);
//Bind the parameter
parm.Value = categoryId;
//Execute the query调用工具底层
using (SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, CommandType.Text, SQL_SELECT_CATEGORY, parm)) {
if (rdr.Read())
category = new CategoryInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));
else
category = new CategoryInfo();
}
return category;
}
四、实体类层 Model项目
为每个表建立一个表瘦实体类
五、数据访问工具类 DBUtility项目
包含两个文件:OracleHelper.cs和SQLHelper.cs分别用于访问Oracle和Sql数据库
服务:(辅助项目)
OrderProcessor项目:订单处理器
这里使用控制台程序的项目来演示如何使用多进程和消息队列处理订单,真正应用时请使用windows服务的方式。
使用消息队列处理订单
Imessaging:消息接口类项目
MessagingFactory:消息工厂项目
MSMQMessaging:消息队列实现项目
IBLLStrategy:插入订单到实体类的接口项目
使用缓存
ICacheDependency:缓存接口项目
CacheDependencyFactory :缓存依赖类的工厂类项目,通过反射调用TableCacheDependency项目,实现接口要求的方法返回缓存实例【见备注4】
TableCacheDependency:缓存依赖实现类项目
Membership Membership认证和授权管理
备注1:
生成实例统一调用数据工厂DALFactory项目,该项目只有唯一一个密封类文件:DataAccess.cs
使用了反射和配置文件的技巧。
其中:
(PetShop.IMessaging.IOrder)Assembly.Load(path).CreateInstance(className);(来源:百度知道)
这段代码使用放射创建 PetShop.IMessaging.IOrder 类型的实例,path为所要加载的程序集路径。
关于反射:
1、可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型
2、应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射。
3、反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。
与工厂模式的联系:
利用反射,在配置文件里定义好类型名,在程序运行时动态创建对象。
Silver:使用反射的方式可以只改配置文件,无需重新编译就能从sql数据库切换到oracle数据库,使用反射虽然会消耗一些性能,但是因为使用静态方式,所以只会消耗一次,无所谓。
备注2:
IDAL接口类被SQL和Oracle两种类型继承
SQL:SQLServerDAL项目
Oracle:OracleDAL项目
IProfileDAL接口类
被SQLProfileDAL项目和OracleProfileDAL项目继承
备注3:
引用三个项目:
using PetShop.Model;(实体类)
using PetShop.IDAL;(接口类)
using PetShop.DBUtility;(数据访问工具类)
备注4:
目的是返回相关的表缓存。
SqlCacheDependency基于表的缓存应用在sql2000,以及slq20005中实现的原理多一样,多是在需要检测的表上建立触发器,并且Asp.net运行时通过轮询机制来检测表数据是否更改.
(已)