ASP.NET Cache 类
1.Nop中没有System.Web.Caching.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(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().As ().Named ("nop_cache_static").SingleInstance(); builder.RegisterType ().As ().Named ("nop_cache_per_request").InstancePerHttpRequest();
注册Service(可以根据实际需求为Service提供不同的缓存方式。)
//pass MemoryCacheManager to SettingService as cacheManager (cache settngs between requests)
builder.RegisterType().As()
.WithParameter(ResolvedParameter.ForNamed("nop_cache_static"))
.InstancePerHttpRequest();
//pass MemoryCacheManager to LocalizationService as cacheManager (cache locales between requests)
builder.RegisterType().As()
.WithParameter(ResolvedParameter.ForNamed("nop_cache_static"))
.InstancePerHttpRequest();
//pass MemoryCacheManager to LocalizedEntityService as cacheManager (cache locales between requests)
builder.RegisterType().As()
.WithParameter(ResolvedParameter.ForNamed("nop_cache_static"))
.InstancePerHttpRequest();
最后是构造器注入
///
/// Provides information about localizable entities
///
public partial class LocalizedEntityService : ILocalizedEntityService
{
///
/// Ctor
///
/// Cache manager
/// Localized property repository
public LocalizedEntityService(ICacheManager cacheManager,
IRepository 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.";
///
/// Gets a blog post
///
/// Blog post identifier
/// Blog post
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;
});
}///
/// Updates the blog post
///
/// Blog post
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缓存全部清空掉。稍微改一下
///
/// Updates the blog post
///
/// Blog post
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类,以及很好的使用实践。非常有借鉴和学习使用的意义。 只需稍微改造一下就可以用于自己的项目中。