入門系列-緩存

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;
    }

    ...
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  •  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章