ABP中有两种cache的实现方式:MemroyCache 和RedisCache,两者都继承至ICache接口(准确说是CacheBase抽象类)。ABP核心模块封装了MemroyCache来实现ABP中的默认缓存功能。 Abp.RedisCache这个模块封装RedisCache来实现缓存(通过StackExchange.Redis这个类库访问redis)。
ABP给出了一个抽象缓存基类。并在内部使用了该抽象基类。使用 MemoryCache 来实现了该抽象基类。它能够被任何其它的缓存类来扩展。Abp.RedisCache 包就扩展了该缓存基类。
ABP对外提供了一个缓存接口ICacheMananger。我们通过构造函数注入这个接口来获取缓存。示例如下:
在这个示例中,我们注入了 ICacheManager接口,s并且获取了一个名称为ControllerCache的缓存。首先我们先对ControllerCache进行清除,然后存入缓存,缓存的名字是大小写敏感的,那就是"ControllerCache"和"CONTROLLERCACHE"取得的缓存内容是不同的。
注意:GetCache方法 千万不要在你的构造函数中使用GetCache方法。如果类不是一个单例对象那么该缓存可能会被dispose掉。
ICacheICacheManager.GetCache方法返回了一个ICache对象。每一个缓存都是基于名称单例存在的。只有首次访问时才会被创建,以后你每次用相同的名称去获取的缓存都是相同的。所以我们可以在不同的类中使用相同的名称来共享相同的缓存。
在示例代码中,我们简单的使用了ICache.Get方法,它有两个参数:
key : 要获取的缓存项的唯一标识符
factory:如果根据给定的key获取到的缓存项为空,那么factory将会创建一个标识符为key的缓存,并且返回该缓存
ICache接口还有其它方法,如前面Clear(),Get(),GetOrDefault,Set,Remove和Clear。当然也有这些方法的异步(async)版本。如下图,我就懒得写了。
ICache 接口用key(字符串类型)来获取缓存value(object类型)。ITypedCache 为ICahe提供了一个 类型安全 的包装;为了使类型安全转换(ICache到ITypedCache),我们可以用扩展方法 AsTyped,而不需要写其它强制类型转换的代码,如下所示:
ITypedCache<int, Item> myCache = _cacheManager.GetCache("MyCache").AsTyped<int, Item>();
缓存的过期时间默认是60分钟。它是变化的。如果你在60分钟内没有使用该缓存,该缓存会被自动的移除。如果你想改变所有的缓存或者指定的缓存来的默认过期时间,你可以这样做,实现如下:
//对所有缓存的配置 Configuration.Caching.ConfigureAll(cache => {
cache.DefaultSlidingExpireTime = TimeSpan.FromHours(2); });
//对指定缓存的配置 Configuration.Caching.Configure("MyCache", cache => {
cache.DefaultSlidingExpireTime = TimeSpan.FromHours(8); });
这段代码你应该放在模块(module)的 PreInitialize 方法中。如上所示:MyCache将会在8小时后过期,而其他的缓存将在2小时后过期。
这些配置将会在首次创建缓存的时候生效。配置不仅仅局限于DefaultSlidingExpireTime,你可以利用ICache接口中的属性获取方法来自由的配置并且初始化它们。
Entity CachingABP的缓存系统是以通用为目的,它有一个 EntityCache 基类,如果你需要的话,这个基类可以帮助你缓存实体。使用这个基类,我们可以通过ID取得实体,并且我们通过ID来缓存实体,这样以后就不需要频繁的查询数据库去取得实体。假设我们有个Person实体,像下面一样:
public class Person : Entity {
public string Name { get; set; }
public int Age { get; set; } }
并且,假设我们通过该实体的Id,需要频繁调用取得Person实体的Name。首先,我们应该创建一个类来存储 cache items:
[AutoMapFrom(typeof(Person))] public class PersonCacheItem {
public string Name { get; set; } }