程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> <<ABP框架>> 緩存,abp框架緩存

<<ABP框架>> 緩存,abp框架緩存

編輯:關於.NET

<<ABP框架>> 緩存,abp框架緩存


簡介

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<Person> 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 是如何工作

  • 在第一個調用裡獲取從倉儲(從數據庫)獲取實體,然後在接下來的調用裡從緩存裡獲取。
  •  如果實體更新或刪除後,它自動使緩存失效,所以它將在下一個調用裡重新從數據庫獲取。
  • 使用IObjectMapper映射到緩存項,AutoMpper模塊實現了IObjectMapper,所以需要AutoMapper模塊。你可以重載MapToCacheItem方法,手動映射實體到緩存項。
  • 使用緩存類全名作為緩存時的名稱,你可以通過傳遞一個緩存名給基構造器來改變它。
  • 是線程安全的。

如果你需要更復雜的緩存技術,你可以擴展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“作為默認連接字符串,你可以在配置文件裡添加連接字符串重寫它,例如:

<add name="Abp.Redis.Cache" connectionString="localhost"/>

同樣,你可以向appSettings裡添加Redis的數據庫Id,例如:

<add key="Abp.Redis.Cache.DatabaseId" value="2"/>

不同的數據庫Id,在同一服務器上,幫助創建不同的鍵空間(獨立緩存)。

UseRedis方法也有一個重載,用給定的action(行為)直接設置選項值(在配置文件中重寫)。

查看更多有關Redis信息及它的配置,請查閱Redis文檔。

 

提醒:Redis服務器應該安裝和運行在ABP裡。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved