NHibernate3剖析:Configuration篇之Cache lambda-configuration配置
在上一篇文章中我们介绍了lambda表达式配置(lambda-configuration)其中还剩下EntityCache扩展方法用于配置Domain的二级缓存。实体缓存配置曾经Fabio Maulo做过一次调查发现几乎没有人在hibernate.cfg.xml或者app.config文件中配置二级缓存发现通常做法是在各个Domain的映射(Mapping)文件中使用cache/配置。我想其中的一个原因是大家还不知道有这个功能。不过在介绍EntityCache扩展方法之前我们还是先回顾下NH2弱类型(Weak Type)的缓存配置吧。实体缓存配置(Weak Type)在hibernate.cfg.xml文件中在session-factory-configuration节点里通过设置class-cache和collection-cache节点配置实体缓存和集合缓存//Code Snippets Copyright http://lyj.cnblogs.com/ class-cache classNameSpace.Entity usageread-only|read-write|nonstrict-read-write|transactional regionARegion/ collection-cache collectionNameSpace.Entity.CollectionProperty usageread-only|read-write|nonstrict-read-write|transactional regionARegion/这样NHibernate通过扫描hibernate.cfg.xml文件然后调用Configuration类中的方法来实现缓存配置所以我们只有手动编写“字符串信息”没法使用强类型。//Code Snippets Copyright http://lyj.cnblogs.com/ public Configuration SetCacheConcurrencyStrategy(String clazz, String concurrencyStrategy) public void SetCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region) public Configuration SetCollectionCacheConcurrencyStrategy(string collectionRole, string concurrencyStrategy)在各个Domain的Mapping文件中我们在class或者集合(set、bag、list、map)节点配置二级缓存//Code Snippets Copyright http://lyj.cnblogs.com/ cache usageread-only|read-write|nonstrict-read-write regionARegion/实体缓存配置(EntityCache)EntityCache原理所谓EntityCache配置就是通过lambda表达式来实现的即在ConfigurationExtensions类中EntityCache扩展方法我们看看这个扩展方法具体实现吧//Code Snippets Copyright http://lyj.cnblogs.com/ public static Configuration EntityCacheTEntity(this Configuration configuration, ActionIEntityCacheConfigurationPropertiesTEntity entityCacheConfiguration) where TEntity : class { var ecc new EntityCacheConfigurationPropertiesTEntity(); entityCacheConfiguration(ecc); if (ecc.Strategy.HasValue) { configuration.SetCacheConcurrencyStrategy(typeof(TEntity).FullName, EntityCacheUsageParser.ToString(ecc.Strategy.Value),ecc.RegionName); } foreach (var collection in ecc.Collections) { configuration.SetCollectionCacheConcurrencyStrategy(collection.Key, EntityCacheUsageParser.ToString(collection.Value.Strategy),collection.Value.RegionName); } return configuration; }我们一看便知就是调用Configuration类中的SetCacheConcurrencyStrategy和SetCollectionCacheConcurrencyStrategy方法实现的。EntityCache使用我们为Domain配置二级缓存首先定义一个Domain实体这个实体中也包含了一个集合//Code Snippets Copyright http://lyj.cnblogs.com/ public class EntityToCache { public string Name { get; set; } public IListstring Elements { get; set; } }我们使用EntityCache扩展方法实践一下吧1.只配置Domain实体二级缓存//Code Snippets Copyright http://lyj.cnblogs.com/ configure.EntityCacheEntityToCache(ce { ce.Strategy EntityCacheUsage.NonStrictReadWrite; ce.RegionName MyRegion; });2.配置Domain实体和它的集合二级缓存//Code Snippets Copyright http://lyj.cnblogs.com/ configure.EntityCacheEntityToCache(ce { ce.Strategy EntityCacheUsage.NonStrictReadWrite; ce.RegionName MyRegion; ce.Collection(e e.Elements, cc { cc.RegionName MyCollectionRegion; cc.Strategy EntityCacheUsage.NonStrictReadWrite; }); });3.只配置集合(不缓存Domain)二级缓存//Code Snippets Copyright http://lyj.cnblogs.com/ configure.EntityCacheEntityToCache(ce ce.Collection(e e.Elements, cc { cc.RegionName MyCollectionRegion; cc.Strategy EntityCacheUsage.NonStrictReadWrite; }));结语在NHibernate3.0中我们可以通过EntityCache扩展方法来实现对实体二级缓存的强类型配置了。有了这个扩展方法大家在一个配置类中配置所有Domain的二级缓存了方便统一管理、随时修改和卸载。但是仔细想想如果项目架构设计不好这会导致配置类所在程序集会引用所有Domain项目而有的Domain项目有时需要引用配置类所在程序集很容易会造成双向引用。为了避免这个问题现在该想想如何设计我们的项目架构咯关于大型项目中使用NHibernate的完美方案有机会慢慢介绍。