微软企业库5.0 学习之路——第十步、使用Unity解耦你的系
统—PART5——使用Unity自身的拦截器
作者:HeroBeast 来源:博客园 发布时间:2010-12-27 10:16 阅读:4 次 原文链接 [收藏]
在前面的企业库学习之路里我分别使用了Data Access构建多数据库访问和使用
Exception Handle+Logging记录系统的异常。今天我来介绍下企业库中的Caching模块在本项目中如何应用。
首先先补习下企业库的Caching Application Block的相关知识:
1、四大缓存方式,在Caching Application Block中,主要提供以下四种保存缓存数据的途径,分别是:内存存储(默认)、独立存储(Isolated Storage)、数据库存储(DataBase Cache Storage)和自定义存储(Custom Cache Storage)。
2、多种存储方式,抛开自定义存储不谈,内存存储是最基本的缓存,仅仅是将数据缓存到内存当中,虽然速度快但是无法进行持久化存储,而独立存储和数据库存储一个是存储到本地的磁盘中(视操作系统不同存储到不同的位置)而另一个则是存储到数据库中(方便进行分布式缓存),所以可以进行持久化保存不会因为关机而丢失(可以到。在EntLib50Src\\Blocks\\Caching\\Src\\Database\\Scripts下找到脚本进行安装) 3、优秀的易用性,虽然在.NET类库System.Web中已经提供了Cache类,但是有局限性,仅可适用于控制台、Winform、Web、服务等。
4、安全性,企业库中的缓存模块可以和加密模块很好的结合起来,当适用数据库缓存、独立存储或者自定义存储的时候可以适用加密模块对缓存的数据进行加密,但存储到内存当中的数据就无法进行加密了。
在了解了缓存的基本知识后我们就可以开始进行具体的操作了。
我现在就是使用Cache模块为项目中反射具体数据库DAL层对象实例进行缓存,这样不用每次在调用底层的时候都反射一次,只需在第1次反射后缓存,以后的访问直接从缓存中读取,提高了访问的速度。
通过企业库配置工具添加个Caching Settings
这里使用默认设置,保存到内存中,过期轮询时间,最大存储数量和移除数量都使用了默认的设置。
如果不想使用默认的内存存储可以建立独立存储或者数据库存储。
这里有个要提的就是企业库的缓存模块的数据库存储是使用存储过程来进行缓存与数据库之间的交互,但是本项目中使用了多数据库,如Sqlite,就无法支持存储过程,所以这边
需要自定义存储方式,可以直接查看企业库代码中
Cache.DataBase.DataBackingStore.cs类,仿照DataBackingStore类自定义一个存储方式,只不过在进行数据库交互的时候使用SQL语句进行。
继续回到主题上,我这边写了一个简单的CacheHelper,用以操作缓存,其中我自定义了一个缓存刷新操作类(此类必须为可序列化),用于将已经过期的对象重新加入到缓存当中,代码如下:
using System;
using System.Collections.Generic; using System.Linq; using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
namespace EntLibStudy.Helper {
public static class CacheHelper {
//2种建立CacheManager的方式
//ICacheManager cache =
EnterpriseLibraryContainer.Current.GetInstance
///
/// ///
///
public static void Add(string key, object value, bool isRefresh = false) {
if (isRefresh) {
//自定义刷新方式,如果过期将自动重新加载,过期时间为5分钟 cache.Add(key, value, CacheItemPriority.Normal, new MyCacheItemRefreshAction(), new
AbsoluteTime(TimeSpan.FromMinutes(5))); } else {
cache.Add(key, value); } }
///
///
/// ///
public static object GetCache(string key) {
return cache.GetData(key); }
///
///
/// public static void RemoveCache(string key) {
cache.Remove(key); } }
///
/// 自定义缓存刷新操作
/// [Serializable]
public class MyCacheItemRefreshAction : ICacheItemRefreshAction {
#region ICacheItemRefreshAction 成员 ///
///
/// /// ///
void ICacheItemRefreshAction.Refresh(string removedKey, object expiredValue, CacheItemRemovedReason removalReason) {
if (removalReason == CacheItemRemovedReason.Expired) {
ICacheManager cache = CacheFactory.GetCacheManager(); cache.Add(removedKey, expiredValue); } }
#endregion
} }
1、缓存等级,在企业库的缓存模块中已经提供了4个缓存等级:Low,Normal,High和NotRemovable,在超出最大缓存数量后会自动根据缓存等级来移除对象。 2、ICacheItemRefreshAction,这个接口用来方便开发人员扩展使用的,开发人员可以根据移除原因在对象过期后进行相应的操作,其中CacheItemRemovedReason分 Expired:过期被移除 Removed:被手动移除
Scavenged:因为缓存数量已满,则根据缓存等级移除较低级的缓存 Unknown:未知移除,不建议使用 3、过期方式,企业库默认提供4种过期方式
AbsoluteTime:绝对是时间过期,传递一个时间对象指定到时过期
SlidingTime:缓存在最后一次访问之后多少时间后过期,默认为2分钟,有2个构造函数可以指定一个过期时间或指定一个过期时间和一个最后使用时间
public SlidingTime(TimeSpan slidingExpiration) {
// Check that expiration is a valid numeric value if (!(slidingExpiration.TotalSeconds >= 1)) {
throw new ArgumentOutOfRangeException(\,
Resources.ExceptionRangeSlidingExpiration); }
this.itemSlidingExpiration = slidingExpiration; }
public SlidingTime(TimeSpan slidingExpiration, DateTime originalTimeStamp) : this(slidingExpiration) {
timeLastUsed = originalTimeStamp; }
ExtendedFormatTime :指定过期格式,以特定的格式来过期,通过
ExtendedFormat.cs类来包装过期方式,具体可参照ExtendedFormat.cs,源代码中已经给出了很多方式
FileDependency:依赖于文件过期,当所依赖的文件被修改则过期,这个我觉得很有用,因为在许多网站,如论坛、新闻系统等都需要大量的配置,可以将配置文件信息进行缓存,将依赖项设为配置文件,这样当用户更改了配置文件后通过
ICacheItemRefreshAction.Refresh可以自动重新缓存。
在介绍了Cache的相关参数后我们来看下具体如何使用,我这边将原来的DataAccess类重新修改了一下,因为觉得如果每次多增加一个数据表,对应的工厂就需要多写一个反射方

