Enterprise Library 提供了 CAB(Caching Application Block) 来帮助开发人员进行数据缓存管理.
其内存缓存的实现倒也简单实用——取一个Hashtable来保存各个缓存项——跟我们自己做的一样,不过其中有个Backing Store的概念,倒是让这个缓存库一下丰富了起来.
看CAB入门文章时,常常会看到介绍它有4种存储方式:
- 内存存储
- 独立文件缓存(Isolated Storage)
- 数据库存储(DataBase Cache Storage)
- 自定义存储
看到这种排版的介绍方式,很容易就将读者导入这样的思维:独立文件存储、数据库存储和自定义存储是跟内存存储同种性质的,可以互相不依赖。
然而事实并非这样。我们来看看一文中的插图:
从这张图中可以看出上面四者的关系:放在 Cache 类中的内存存储属于缓存主体,而其它几种存储方式仅仅是作为其后备存储(Backing Store)而已。
以Database cache storage为例,当我们用CAB提供的SQL脚本创建了数据库,并在Config文件中作好了相应的配置后,如无差错,程序运行时每一次执行CacheManager.Add方法,就会发现Cache数据库中对应表会多出一条记录。如果以为Get的时候也是实时从该表中取的,那就上了大当了。所谓Backing Store,就只是内存缓存的一个备份而已。备份的原因是要避免程序重启内存数据丢失从而内存缓存一并丢失的问题。
查看CAB的源代码,会发现CacheManager在初始化的时候会调用BackingStore.Load方法将Backing Storage中的数据读进内存,以后的每一次缓存项修改操作(添加、移除等),都会将Backing Storage中的数据更新。
一些头脑灵活的同学会问那每次都去新建一个CacheManager岂不是就变成完全采用Backing Storage作为缓存存储了?
答案是不会。CAB的源代码中是通过调用ServiceLocation.GetInstance()来创建CacheManager的,而ServiceLocation.GetInstance()创建的对象是单例模式的,也就是说,无论new几次,返回的都是第一次新建的那个CacheManager实例对象.
不知道EntLib下一个版本什么时候出,其文档说要将CAB改成依赖于Framework中的Cache对象的方式,期待中.