• 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类,以及很好的使用实践。非常有借鉴和学习使用的意义。 只需稍微改造一下就可以用于自己的项目中。

  • 相关阅读:
    Mutex 的正确打开方式
    常用 CMD 命令
    【LeetCode】在排序数组中查找元素的第一个和最后一个位置【三次二分】
    【LeetCode】搜索旋转排序数组【两次二分】
    【手写代码】计算1-n中总共有多少二进制1
    【手写代码】快速计算数字x有多少个二进制1
    【手写代码】建立二叉搜索树
    【LeetCode】下一个排列【找规律】
    【LeetCode】删除排序数组中的重复项&&移除特定元素【双指针,原地算法】
    【LeetCode】删除链表的倒数第N个节点【双指针法】
  • 原文地址:https://www.cnblogs.com/miku/p/2698478.html
Copyright © 2020-2023  润新知