ABP框架擴展了ASP.NET Core的分佈式緩存系統.
Volo.Abp.Caching Package
默認情況下啓動模板已經安裝了這個包,所以大部分情況下你不需要手動安裝.
Volo.Abp.Caching是緩存系統的核心包.使用包管理控制檯(PMC)安裝到項目:
Install-Package Volo.Abp.Caching
然後將 AbpCachingModule 依賴添加到你的模塊:
using Volo.Abp.Modularity;
using Volo.Abp.Caching;
namespace MyCompany.MyProject
{
[DependsOn(typeof(AbpCachingModule))]
public class MyModule : AbpModule
{
//...
}
}
IDistributedCache
接口
ASP.NET Core 定義了 IDistributedCache
接口用於 get/set 緩存值 . 但是會有以下問題:
- 它適用於 byte 數組 而不是 .NET 對象. 因此你需要對緩存的對象進行序列化/反序列化.
- 它爲所有的緩存項提供了 單個 key 池 , 因此 ;
- 你需要注意鍵區分 不同類型的對象.
- 你需要注意不同租戶(參見多租戶)的緩存項.
IDistributedCache
定義在Microsoft.Extensions.Caching.Abstractions
包中. 這使它不僅適用於ASP.NET Core應用程序, 也可用於任何類型的程序.
IDistributedCache
接口的默認實現是MemoryDistributedCache
它使用內存工作. 參見 ASP.NET Core文檔 瞭解如何切換到 Redis 或其他緩存提供程序.
有關更多信息, 參見 ASP.NET Core 分佈式緩存文檔.
IDistributedCache<TCacheItem>
接口
ABP框架在Volo.Abp.Caching包定義了通用的泛型 IDistributedCache<TCacheItem>
接口. TCacheItem
是存儲在緩存中的對象類型.
IDistributedCache<TCacheItem>
接口了上述中的問題;
- 它在內部 序列化/反序列化 緩存對象. 默認使用 JSON 序列化, 但可以替換依賴注入系統中
IDistributedCacheSerializer
服務的實現來覆蓋默認的處理. - 它根據緩存中對象類型自動向緩存key添加 緩存名稱 前綴. 默認緩存名是緩存對象類的全名(如果你的類名以
CacheItem
結尾, 那麼CacheItem
會被忽略,不應用到緩存名稱上). 你也可以在緩存類上使用CacheName
設置換緩存的名稱. - 它自動將當前的租戶id添加到緩存鍵中, 以區分不同租戶的緩存項 (只有在你的應用程序是多租戶的情況下生效). 在緩存類上應用
IgnoreMultiTenancy
attribute, 可以在所有的租戶間共享緩存. - 允許爲每個應用程序定義 全局緩存鍵前綴 ,不同的應用程序可以在共享的分佈式緩存中擁有自己的隔離池.
使用方式
緩存中存儲項的示例類:
public class BookCacheItem
{
public string Name { get; set; }
public float Price { get; set; }
}
你可以注入 IDistributedCache<BookCacheItem>
服務用於 get/set BookCacheItem
對象。
使用示例:
public class BookService : ITransientDependency
{
private readonly IDistributedCache<BookCacheItem> _cache;
public BookService(IDistributedCache<BookCacheItem> cache)
{
_cache = cache;
}
public async Task<BookCacheItem> GetAsync(Guid bookId)
{
return await _cache.GetOrAddAsync(
bookId.ToString(), //Cache key
async () => await GetBookFromDatabaseAsync(bookId),
() => new DistributedCacheEntryOptions
{
AbsoluteExpiration = DateTimeOffset.Now.AddHours(1)
}
);
}
private Task<BookCacheItem> GetBookFromDatabaseAsync(Guid bookId)
{
//TODO: get from database
}
}
- 示例服務代碼中的
GetOrAddAsync()
方法從緩存中獲取圖書項. - 如果沒有在緩存中找到圖書,它會調用工廠方法 (本示例中是
GetBookFromDatabaseAsync
)從原始數據源中獲取圖書項. GetOrAddAsync
有一個可選參數DistributedCacheEntryOptions
, 可用於設置緩存的生命週期.
IDistributedCache<BookCacheItem>
的其他方法與ASP.NET Core的IDistributedCache
接口相同, 你可以參考 ASP.NET Core文檔.
IDistributedCache<TCacheItem, TCacheKey>
接口
IDistributedCache<TCacheItem>
接口默認了鍵是 string
類型 (如果你的鍵不是string類型需要進行手動類型轉換). IDistributedCache<TCacheItem, TCacheKey>
將鍵的類型泛型化試圖簡化手動轉換的操作.
使用示例
示例緩存項
public class BookCacheItem
{
public string Name { get; set; }
public float Price { get; set; }
}
用法示例 (這裏假設你的鍵類型是 Guid
):
public class BookService : ITransientDependency
{
private readonly IDistributedCache<BookCacheItem, Guid> _cache;
public BookService(IDistributedCache<BookCacheItem, Guid> cache)
{
_cache = cache;
}
public async Task<BookCacheItem> GetAsync(Guid bookId)
{
return await _cache.GetOrAddAsync(
bookId, //Guid type used as the cache key
async () => await GetBookFromDatabaseAsync(bookId),
() => new DistributedCacheEntryOptions
{
AbsoluteExpiration = DateTimeOffset.Now.AddHours(1)
}
);
}
private Task<BookCacheItem> GetBookFromDatabaseAsync(Guid bookId)
{
//TODO: get from database
}
}
- 示例服務中
GetOrAddAsync()
方法獲取緩存的圖書項. - 我們採用了
Guid
做爲鍵,在_cache_GetOrAddAsync()
方法中傳入Guid
類型的bookid。
IDistributedCache<TCacheItem, TCacheKey>
在內部使用鍵對象的 ToString()
方法轉換類型爲string. 如果你的將複雜對象做爲鍵,那麼需要重寫類的 ToString
方法。
示例:
public class UserInOrganizationCacheKey
{
public Guid UserId { get; set; }
public Guid OrganizationId { get; set; }
//構建緩存key
public override string ToString()
{
return $"{UserId}_{OrganizationId}";
}
}
用法示例:
public class BookService : ITransientDependency
{
private readonly IDistributedCache<UserCacheItem, UserInOrganizationCacheKey> _cache;
public BookService(<UserCacheItem, UserInOrganizationCacheKey> cache)
{
_cache = cache;
}
...
}