简介
ABP 提供了一个缓存接口,它内部使用了这个缓存接口。虽然接口的默认实现是 MemoryCache,但可以用任何其它实现的缓存供应器。Abp.RedisCache 包用 Redis 实现了缓存(查看下方的 "Redis 缓存集成")。
ICacheManager
缓存的主要接口是 ICacheManager。我们可以注入它并用它获取一个缓存,如:
- public class TestAppService: ApplicationService {
- private readonly ICacheManager _cacheManager;
- public TestAppService(ICacheManager cacheManager) {
- _cacheManager = cacheManager;
- }
- public Item GetItem(int id) {
- //Try to get from cache
- return _cacheManager.GetCache("MyCache").Get(id.ToString(), () = >GetFromDatabase(id)) as Item;
- }
- public Item GetFromDatabase(int id) {
- //... retrieve item from database
- }
- }
在此例里,我们注入了 ICacheManager,并获得一个名为 MyCache 的缓存。
警告:GetCache 方法
如果你的类不是单例,不要在你构造器里使用 GetCache,否则可能会销毁你的缓存。
ICache
ICacheManager.GetCache 方法返回一个 ICache。一个缓存是单例的(每个缓存名)。第一次请求时创建,然后一直返回同一个缓存对象。所以,我们可以在不同的类(客户端)里用相同的名字共享同一个缓存。
在示例代码里,我们看到了 ICache.get 方法的简单使用。它有两个参数:
key:字符串,必需,一个缓存项的键。
factory:一个 action(行为),在找不到指定 key 的缓存项时调用,Factory 方法应该创建并返回切实的项,如果指定 key 的缓存已存在,就不调用。
ICache 接口也有如 GetOrDefault、Set、Remove 和 Clear 等方法。同样也有 async 版本。
ITypedCache
ICache 接口以字符串为 key,值是 object 类型。ITypedCache 包装了 ICache 并提供了类型安全、泛型。我们可用泛型的 GetCache 扩展方法,获取一个 ITypedCache:
- ITypedCache < int,
- Item > myCache = _cacheManager.GetCache < int,
- Item > ("MyCache");
同样,我们也可用 AsTyped 扩展方法,把一个已存在的 ICache 实例转换成 ITypedCache。
配置
默认缓存超时是 60 分钟,它可以改。如果你超过 60 分钟没有使用缓存中的项,会从缓存中自动移除。你可以配置指定的缓存或是全部的缓存。
- //Configuration for all caches
- Configuration.Caching.ConfigureAll(cache = >{
- cache.DefaultSlidingExpireTime = TimeSpan.FromHours(2);
- });
- //Configuration for a specific cache
- Configuration.Caching.Configure("MyCache", cache = >{
- cache.DefaultSlidingExpireTime = TimeSpan.FromHours(8);
- });
这段代码应该写在你模块的 PreInitialize 方法里,用这段代码,MyCache 将有 8 个小时的超时时间,其它的缓存有 2 个小时。
在第一次创建缓存(在第一次请求)调用你的配置行为。配置不仅限于 DefaultSlidingExpireTime,由于缓存对象是一个 ICache,所以你可以用它的属性和方法,自由的配置和初始化。
实体缓存
虽然 ABP 缓存系统出于普通的目的,但有一个 EntityCache 基类,可帮你缓存实体。如果我们通过它们的 Id 获取的实体,我们可以用这个基类缓存它们,就不用再频繁地从数据库查询。假设我们有如下所示的一个 person 实体:
- public class Person: Entity {
- public string Name {
- get;
- set;
- }
- public int Age {
- get;
- set;
- }
- }
并假设我们已经知道 Id,要频繁地获取 Name。首先,我们需要创建一个类来缓存项:
- [AutoMapFrom(typeof(Person))] public class PersonCacheItem {
- public string Name {
- get;
- set;
- }
- }
我们不应该直接在缓存里存储实体,由于缓存可能需要序列化缓存对象,而实体不一定能序列化(尤其有导航属性的实体)。这就是为什么我们创建一个简单(像 DTO:数据传输对象)类存储数据。添加 AutoMapFrom 特性,它可以自动地把 Person 转换成 PersonCacheItem 对象。如果我们不使用 AutoMapFrom,我们应该为重载 EntityCache 类的 MapToCacheItem 方法,手动转换 / 映射。
虽然不是必需,但我们可能想为我们的缓存类定义一个接口:
- public interface IPersonCache: IEntityCache < PersonCacheItem > {}
最后,我们可以为实体创建缓存类:
- public class PersonCache: EntityCache < Person,
- PersonCacheItem > ,
- IPersonCache,
- ITransientDependency {
- public PersonCache(ICacheManager cacheManager, IRepository repository) : base(cacheManager, repository) {}
- }
这就是全部代码,我们的 Person 缓存已经可用。缓存类可以是暂时的(如示例)或单体的,这不是说缓存的数据是暂时的,它始终在你的应用里是全局的并线程安全的。
现在,任何需要 Person 的 Name 时,我们可以通过 person 的 Id 从缓存获取,使用 Person 缓存的示例如下:
- public class MyPersonService: ITransientDependency {
- private readonly IPersonCache _personCache;
- public MyPersonService(IPersonCache personCache) {
- _personCache = personCache;
- }
- public string GetPersonNameById(int id) {
- return _personCache[id].Name; //alternative: _personCache.Get(id).Name;
- }
- }
我们简单地注入 IPersonCache,获取缓存项和获取 Name 属性。
EntityCache 是如何工作
如果你需要更复杂的缓存技术,你可以扩展 EntityCache 或创建你自己的解决方案。
Redis 缓存集成
默认缓存管理使用的是内存缓存。所以,如果你有多个并发的 web 服务器使用同个应用,可能会成为一个问题,在这种情况下,你需要一个分布 / 集中缓存服务,你就可以简单的使用 Redis 做为你的缓存服务器。
首先,你要在你的应用里,安装 Abp.RedisCache 的 Nuget 包(例如,你可在你的 Web 项目里安装)。接着为 AbpRedisCacheModule 添加 DependsOn 特性,然后在你模块预初始化方法里调用 useRedis 扩展方法。如下所示:
- //...other namespaces
- using Abp.Runtime.Caching.Redis;
- namespace MyProject.AbpZeroTemplate.Web { [DependsOn(
- //...other module dependencies
- typeof(AbpRedisCacheModule))] public class MyProjectWebModule: AbpModule {
- public override void PreInitialize() {
- //...other configurations
- Configuration.Caching.UseRedis();
- }
- //...other code
- }
- }
Abp.RedisCache 包使用 "localhost" 作为默认连接字符串,你可以在配置文件里添加连接字符串重写它,例如:
- "Abp.Redis.Cache"connectionString = "localhost" / >
同样,你可以向 appSettings 里添加 Redis 的数据库 Id,例如:
- "Abp.Redis.Cache.DatabaseId"value = "2" / >
不同的数据库 Id,在同一服务器上,帮助创建不同的键空间(独立缓存)。
UseRedis 方法也有一个重载,用给定的 action(行为)直接设置选项值(在配置文件中重写)。
查看更多有关 Redis 信息及它的配置,请查阅。
提醒:Redis 服务器应该安装和运行在 ABP 里。
来源: http://www.cnblogs.com/kid1412/p/5987083.html