ASP.NET Cache 類


 

在查找資料的過程中。原來園子里面已經有過分析了。nopCommerce架構分析系列(二)數據Cache。 接下來是一些學習補充。

 

1.Nop中沒有System.Web.Caching.Cache的實現。原因暫不明。先自己實現一個吧

using System;
using System.Collections.Generic;
using System.Web;
using System.Runtime.CompilerServices;
using System.Web.Caching;
using System.Collections;
using System.Text.RegularExpressions;

namespace SDF.Core.Caching
{

    public class CacheManager : ICacheManager
    {
        System.Web.Caching.Cache Cache = HttpRuntime.Cache;

        public void Set(string key, object data)
        {
            Cache.Insert(key, data);
        }
        public void Set(string key, object data, DateTime absoluteExpiration, TimeSpan slidingExpiration)
        {
            Cache.Insert(key, data, null,absoluteExpiration, slidingExpiration);
        }

        public object Get(string Key)
        {
            return Cache[Key];
        }

        public T Get<T>(string key)
        {
            return (T)Cache[key];
        }

        public bool IsSet(string key)
        {
            return Cache[key] != null;
        }

        public void Remove(string Key)
        {
            if (Cache[Key] != null) {
                Cache.Remove(Key);
            }
        }

        public void RemoveByPattern(string pattern)
        {
            IDictionaryEnumerator enumerator = Cache.GetEnumerator();
            Regex rgx = new Regex(pattern, (RegexOptions.Singleline | (RegexOptions.Compiled | RegexOptions.IgnoreCase)));
            while (enumerator.MoveNext()) {
                if (rgx.IsMatch(enumerator.Key.ToString())) {
                    Cache.Remove(enumerator.Key.ToString());
                }
            }
        }

        public void Clear()
        {
            IDictionaryEnumerator enumerator = Cache.GetEnumerator();
            while (enumerator.MoveNext())
            {
                Cache.Remove(enumerator.Key.ToString());
            }
        }

    }

}

 

 

2.MemoryCache 和 ASP.NET Cache 區別。

引用MSDN

MemoryCache 類類似於 ASP.NET Cache 類。 MemoryCache 類有許多用於訪問緩存的屬性和方法,如果您使用過 ASP.NET Cache 類,您將熟悉這些屬性和方法。 Cache 和 MemoryCache 類之間的主要區別是:MemoryCache 類已被更改,以便 .NET Framework 應用程序(非 ASP.NET 應用程序)可以使用該類。 例如,MemoryCache 類對 System.Web 程序集沒有依賴關系。 另一個差別在於您可以創建 MemoryCache 類的多個實例,以用於相同的應用程序和相同的 AppDomain 實例。

代碼更清楚一點:

[Test]
        public void MemoryCacheTest()
        {
            var cache = new MemoryCache("cache1");
            var cache2 = new MemoryCache("cache2");
            var policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(60);
            cache.Set(new CacheItem("key1", "data1"), policy);

            var obj = cache.Get("key1");
            Assert.IsNotNull(obj);

            var obj2 = cache2.Get("key1");
            Assert.IsNull(obj2);
        }

 

3.Nop中IOC和ICache

注冊CacheManager

//cache manager
            builder.RegisterType<MemoryCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_static").SingleInstance();
            builder.RegisterType<PerRequestCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_per_request").InstancePerHttpRequest();

 

注冊Service(可以根據實際需求為Service提供不同的緩存方式。)

//pass MemoryCacheManager to SettingService as cacheManager (cache settngs between requests)
            builder.RegisterType<SettingService>().As<ISettingService>()
                .WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
                .InstancePerHttpRequest();
            //pass MemoryCacheManager to LocalizationService as cacheManager (cache locales between requests)
            builder.RegisterType<LocalizationService>().As<ILocalizationService>()
                .WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
                .InstancePerHttpRequest();

            //pass MemoryCacheManager to LocalizedEntityService as cacheManager (cache locales between requests)
            builder.RegisterType<LocalizedEntityService>().As<ILocalizedEntityService>()
                .WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
                .InstancePerHttpRequest();

 

最后是構造器注入

/// <summary>
    /// Provides information about localizable entities
    /// </summary>
    public partial class LocalizedEntityService : ILocalizedEntityService
    {
     /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="cacheManager">Cache manager</param>
        /// <param name="localizedPropertyRepository">Localized property repository</param>
        public LocalizedEntityService(ICacheManager cacheManager,
            IRepository<LocalizedProperty> localizedPropertyRepository)
        {
            this._cacheManager = cacheManager;
            this._localizedPropertyRepository = localizedPropertyRepository;
        }
    }

 

4.Cache的使用

 

一段Nop中的代碼

 

private const string BLOGPOST_BY_ID_KEY = "Nop.blogpost.id-{0}";
       private const string BLOGPOST_PATTERN_KEY = "Nop.blogpost.";

/// <summary>
        /// Gets a blog post
        /// </summary>
        /// <param name="blogPostId">Blog post identifier</param>
        /// <returns>Blog post</returns>
        public virtual BlogPost GetBlogPostById(int blogPostId)
        {
            if (blogPostId == 0)
                return null;

            string key = string.Format(BLOGPOST_BY_ID_KEY, blogPostId);
            return _cacheManager.Get(key, () =>
            {
                var pv = _blogPostRepository.GetById(blogPostId);
                return pv;
            });
        }/// <summary>
       /// Updates the blog post
       /// </summary>
       /// <param name="blogPost">Blog post</param>
       public virtual void UpdateBlogPost(BlogPost blogPost)
       {
           if (blogPost == null)
               throw new ArgumentNullException("blogPost");

           _blogPostRepository.Update(blogPost);

           _cacheManager.RemoveByPattern(BLOGPOST_PATTERN_KEY);

           //event notification
           _eventPublisher.EntityUpdated(blogPost);
       }

 

在查找數據時,會先從緩存中讀取,更新數據時再清空緩存。 但是在這里Update了一個blogPost對象。沒有必要把所有的blogPost緩存全部清空掉。稍微改一下

 

/// <summary>
        /// Updates the blog post
        /// </summary>
        /// <param name="blogPost">Blog post</param>
        public virtual void UpdateBlogPostV2(BlogPost blogPost)
        {
            if (blogPost == null)
                throw new ArgumentNullException("blogPost");

            _blogPostRepository.Update(blogPost);

            string key = string.Format(BLOGPOST_BY_ID_KEY, blogPost.Id);
            _cacheManager.Remove(key);

            //event notification
            _eventPublisher.EntityUpdated(blogPost);
        }

 

總結:nop提供了易於擴展的Cache類,以及很好的使用實踐。非常有借鑒和學習使用的意義。 只需稍微改造一下就可以用於自己的項目中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM