想回家种地养猪

导航

ABP框架详解(七)Caching

  在ABP框架中存在一个缓存机制,使用ICache的继承类来存储最终需要缓存的数据,可以吧ICache看成一个字典对象,使用Key作为真实数据的具有唯一性的表示。使用上与字典对象完全相同,Get方法传递Key,还有数据工厂作为参数就能返回最终的值,Set方法用于存储。包含一个TimeSpan属性用于指定最长不使用数据的过期时间。

/// <summary>
    /// Defines a cache that can be store and get items by keys.
    /// </summary>
    public interface ICache : IDisposable
    {
        /// <summary>
        /// Unique name of the cache.
        /// </summary>
        string Name { get; }

        /// <summary>
        /// Default sliding expire time of cache items.
        /// Default value: 60 minutes. Can be changed by configuration.
        /// </summary>
        TimeSpan DefaultSlidingExpireTime { get; set; }

        /// <summary>
        /// Gets an item from the cache.
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="factory">Factory method to create cache item if not exists</param>
        /// <returns>Cached item</returns>
        object Get(string key, Func<string, object> factory);

        /// <summary>
        /// Gets an item from the cache.
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="factory">Factory method to create cache item if not exists</param>
        /// <returns>Cached item</returns>
        Task<object> GetAsync(string key, Func<string, Task<object>> factory);

        /// <summary>
        /// Gets an item from the cache or null if not found.
        /// </summary>
        /// <param name="key">Key</param>
        /// <returns>Cached item or null if not found</returns>
        object GetOrDefault(string key);

        /// <summary>
        /// Gets an item from the cache or null if not found.
        /// </summary>
        /// <param name="key">Key</param>
        /// <returns>Cached item or null if not found</returns>
        Task<object> GetOrDefaultAsync(string key);

        /// <summary>
        /// Saves/Overrides an item in the cache by a key.
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="value">Value</param>
        /// <param name="slidingExpireTime">Sliding expire time</param>
        void Set(string key, object value, TimeSpan? slidingExpireTime = null);

        /// <summary>
        /// Saves/Overrides an item in the cache by a key.
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="value">Value</param>
        /// <param name="slidingExpireTime">Sliding expire time</param>
        Task SetAsync(string key, object value, TimeSpan? slidingExpireTime = null);

        /// <summary>
        /// Removes a cache item by it's key.
        /// </summary>
        /// <param name="key">Key</param>
        void Remove(string key);

        /// <summary>
        /// Removes a cache item by it's key (does nothing if given key does not exists in the cache).
        /// </summary>
        /// <param name="key">Key</param>
        Task RemoveAsync(string key);

        /// <summary>
        /// Clears all items in this cache.
        /// </summary>
        void Clear();

        /// <summary>
        /// Clears all items in this cache.
        /// </summary>
        Task ClearAsync();
    }

 

  框架中提供了一个ICache的抽象实现类CacheBase,作为所有具体缓存方式的基类,实现了所有基础逻辑,最终的Cache对象只需继承CacheBase,并重写object GetOrDefault(string key),void Set(string key, object value, TimeSpan? slidingExpireTime = null),void Clear()等三个抽象方法就可以完成一个真实可用的缓存Cache(另外Dispose方法通常是需要重写)。同时CacheBase的所有其他公共方法也是可重写的。ABP中默认提供了一个以内存方式缓存数据的实现即AbpMemoryCache,只是简单实用微软的MemoryCache类作为内部缓存容器。

  ICacheManager使用单例模式用于管理所有的ICache,其中包含一个传递Key返回ICache的GetCache方法,还有一个返回所有ICache的GetAllCaches方法,在调用GetCache传递Key的时候如果不存在就会创建一个新的保存起来,对于ICacheManager框架中已经存在一个名为CacheManagerBase的抽象实现了,其内部有一个线程安全的字典用于存放所有的ICache,用于需要继承CacheManagerBase实现自身的CacheManager,只需要实现抽象方法CreateCacheImplementation就行了,最简单的方式就是在方法内部返回一个AbpMemoryCache实例就行了

/// <summary>
    /// An upper level container for <see cref="ICache"/> objects. 
    /// A cache manager should work as Singleton and track and manage <see cref="ICache"/> objects.
    /// </summary>
    public interface ICacheManager : IDisposable
    {
        /// <summary>
        /// Gets all caches.
        /// </summary>
        /// <returns>List of caches</returns>
        IReadOnlyList<ICache> GetAllCaches();

        /// <summary>
        /// Gets (or creates) a cache.
        /// </summary>
        /// <param name="name">Unique name of the cache</param>
        /// <returns>The cache reference</returns>
        ICache GetCache(string name);
    }

  缓存机制中存在一个ICachingConfiguration的配置类,用户可以在自定义的模块中添加ICache的初始化处理逻辑,通常是一个Action<ICache>的委托,添加到配置类的Configurators属性中,每次被创建一个新的ICache对象的时候都会遍历Configurators属性中名称与新建ICache相同,或者无名称的全局性Action<ICache>,用来初始化ICache。

/// <summary>
    /// Used to configure caching system.
    /// </summary>
    public interface ICachingConfiguration
    {
        /// <summary>
        /// List of all registered configurators.
        /// </summary>
        IReadOnlyList<ICacheConfigurator> Configurators { get; }

        /// <summary>
        /// Used to configure all caches.
        /// </summary>
        /// <param name="initAction">
        /// An action to configure caches
        /// This action is called for each cache just after created.
        /// </param>
        void ConfigureAll(Action<ICache> initAction);

        /// <summary>
        /// Used to configure a specific cache. 
        /// </summary>
        /// <param name="cacheName">Cache name</param>
        /// <param name="initAction">
        /// An action to configure the cache.
        /// This action is called just after the cache is created.
        /// </param>
        void Configure(string cacheName, Action<ICache> initAction);
    }
/// <summary>
    /// A registered cache configurator.
    /// </summary>
    public interface ICacheConfigurator
    {
        /// <summary>
        /// Name of the cache.
        /// It will be null if this configurator configures all caches.
        /// </summary>
        string CacheName { get; }

        /// <summary>
        /// Configuration action. Called just after the cache is created.
        /// </summary>
        Action<ICache> InitAction { get; }
    }

  另外因为所有数据都是以字符串为Key,值为Object的方式存储的,所以对于一些依赖强类型的使用不太方便,作者也添加了ITypedCache<TKey,TValue>的方式,用于返回强类型的数据,虽然使用方便的,但是ICache所能缓存的对象也有了限制。

  另外在WebApi端的存储,作者新建一个独立的AbpCacheController控制器,新建了几个Clear方法方便用户(通常是系统管理员级别的)通过远程调用WebApi方法的方式来清理缓存,为了安全起见需要提供一个安全验证码的,原生的是在SettingManager中写死一个密码参数和值,只要告诉管理员密码就行了,在访问AbpCacheController的Clear方法的时候提供预先知道的密码就有权限修改了,这个是非常不方便的,所以建议为清理缓存设置一个单独的Permission,并且添加一个AOP(WebApi的ActionFilter或者直接在AbpApiAuthorieAttribute中)根据当前用户的IAbpSession查看是否有权限清理Cache。

  

posted on 2016-02-22 21:25  想回家种地养猪  阅读(1215)  评论(0编辑  收藏  举报