Skip to content

Commit 9a0178d

Browse files
committed
Implemented IRequestCache to better distinguish between application and request scoped storage (abstraction was a bit messy anyway)
1 parent 0611c10 commit 9a0178d

49 files changed

Lines changed: 337 additions & 190 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace SmartStore.Core.Caching
5+
{
6+
/// <summary>
7+
/// Request cache interface
8+
/// </summary>
9+
public interface IRequestCache
10+
{
11+
/// <summary>
12+
/// Gets a cache item associated with the specified key
13+
/// </summary>
14+
/// <typeparam name="T">The type of the item to get</typeparam>
15+
/// <param name="key">The cache item key</param>
16+
/// <returns>Cached item value or <c>null</c> if item with specified key does not exist in the cache</returns>
17+
T Get<T>(string key);
18+
19+
/// <summary>
20+
/// Gets a cache item associated with the specified key or adds the item
21+
/// if it doesn't exist in the cache.
22+
/// </summary>
23+
/// <typeparam name="T">The type of the item to get or add</typeparam>
24+
/// <param name="key">The cache item key</param>
25+
/// <param name="acquirer">Func which returns value to be added to the cache</param>
26+
/// <returns>Cached item value</returns>
27+
T Get<T>(string key, Func<T> acquirer);
28+
29+
/// <summary>
30+
/// Adds a cache item with the specified key
31+
/// </summary>
32+
/// <param name="key">Key</param>
33+
/// <param name="value">Value</param>
34+
void Set(string key, object value);
35+
36+
/// <summary>
37+
/// Gets a value indicating whether the value associated with the specified key is cached
38+
/// </summary>
39+
/// <param name="key">key</param>
40+
/// <returns>Result</returns>
41+
bool Contains(string key);
42+
43+
/// <summary>
44+
/// Removes the value with the specified key from the cache
45+
/// </summary>
46+
/// <param name="key">/key</param>
47+
void Remove(string key);
48+
49+
/// <summary>
50+
/// Removes items by pattern
51+
/// </summary>
52+
/// <param name="pattern">pattern</param>
53+
void RemoveByPattern(string pattern);
54+
55+
/// <summary>
56+
/// Clear all cache data
57+
/// </summary>
58+
void Clear();
59+
}
60+
61+
/// <summary>
62+
/// For testing purposes
63+
/// </summary>
64+
public class NullRequestCache : IRequestCache
65+
{
66+
private static readonly IRequestCache s_instance = new NullRequestCache();
67+
68+
public static IRequestCache Instance
69+
{
70+
get { return s_instance; }
71+
}
72+
73+
public void Clear()
74+
{
75+
}
76+
77+
public bool Contains(string key)
78+
{
79+
return false;
80+
}
81+
82+
public T Get<T>(string key)
83+
{
84+
return default(T);
85+
}
86+
87+
public T Get<T>(string key, Func<T> acquirer)
88+
{
89+
return default(T);
90+
}
91+
92+
public void Remove(string key)
93+
{
94+
}
95+
96+
public void RemoveByPattern(string pattern)
97+
{
98+
}
99+
100+
public void Set(string key, object value)
101+
{
102+
}
103+
}
104+
}

src/Libraries/SmartStore.Core/Caching/RequestCache.cs

Lines changed: 100 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2,102 +2,128 @@
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.Linq;
5+
using System.Text.RegularExpressions;
56
using System.Web;
67

78
namespace SmartStore.Core.Caching
89
{
9-
10-
public partial class RequestCache : ICache
11-
{
12-
private const string RegionName = "$$SmartStoreNET$$";
13-
private readonly HttpContextBase _context;
14-
15-
public RequestCache(HttpContextBase context)
16-
{
17-
this._context = context;
18-
}
19-
20-
protected IDictionary GetItems()
21-
{
22-
if (_context != null)
23-
return _context.Items;
24-
25-
return null;
26-
}
27-
28-
public IEnumerable<KeyValuePair<string, object>> Entries
29-
{
30-
get
31-
{
32-
var items = GetItems();
33-
if (items == null)
34-
yield break;
35-
36-
var enumerator = items.GetEnumerator();
37-
while (enumerator.MoveNext())
38-
{
39-
string key = enumerator.Key as string;
40-
if (key == null)
41-
continue;
42-
if (key.StartsWith(RegionName))
43-
{
44-
yield return new KeyValuePair<string, object>(key.Substring(RegionName.Length), enumerator.Value);
45-
}
46-
}
47-
}
48-
}
49-
50-
public object Get(string key)
51-
{
52-
var items = GetItems();
53-
if (items == null)
54-
return null;
55-
56-
return items[BuildKey(key)];
57-
}
58-
59-
public void Set(string key, object value, int? cacheTime)
10+
public class RequestCache : IRequestCache
11+
{
12+
const string RegionName = "SmartStoreNET:";
13+
14+
private IDictionary _emptyDictionary = new Dictionary<string, object>();
15+
16+
private readonly HttpContextBase _context;
17+
18+
public RequestCache(HttpContextBase context)
19+
{
20+
_context = context;
21+
}
22+
23+
public T Get<T>(string key)
24+
{
25+
return Get<T>(key, null);
26+
}
27+
28+
public T Get<T>(string key, Func<T> acquirer)
6029
{
6130
var items = GetItems();
62-
if (items == null)
63-
return;
6431

6532
key = BuildKey(key);
6633

34+
if (items.Contains(key))
35+
{
36+
return (T)items[key];
37+
}
38+
39+
if (acquirer != null)
40+
{
41+
var value = acquirer();
42+
items.Add(key, value);
43+
return value;
44+
}
45+
46+
return default(T);
47+
}
48+
49+
public void Set(string key, object value)
50+
{
51+
var items = GetItems();
52+
53+
key = BuildKey(key);
54+
6755
if (items.Contains(key))
6856
items[key] = value;
6957
else
7058
items.Add(key, value);
7159
}
7260

73-
public bool Contains(string key)
74-
{
75-
var items = GetItems();
76-
if (items == null)
77-
return false;
61+
public void Clear()
62+
{
63+
RemoveByPattern("*");
64+
}
65+
66+
public bool Contains(string key)
67+
{
68+
return GetItems().Contains(BuildKey(key));
69+
}
7870

79-
return items.Contains(BuildKey(key));
80-
}
71+
public void Remove(string key)
72+
{
73+
GetItems().Remove(BuildKey(key));
74+
}
8175

82-
public void Remove(string key)
83-
{
84-
var items = GetItems();
85-
if (items == null)
86-
return;
76+
public void RemoveByPattern(string pattern)
77+
{
78+
var items = GetItems();
8779

88-
items.Remove(BuildKey(key));
89-
}
80+
var keysToRemove = Keys(pattern).ToArray();
9081

91-
private string BuildKey(string key)
92-
{
93-
return key.HasValue() ? RegionName + key : null;
94-
}
82+
foreach (string key in keysToRemove)
83+
{
84+
items.Remove(key);
85+
}
86+
}
9587

96-
public bool IsSingleton
88+
protected IDictionary GetItems()
9789
{
98-
get { return false; }
90+
return _context.Items ?? _emptyDictionary;
9991
}
10092

101-
}
93+
public IEnumerable<string> Keys(string pattern)
94+
{
95+
var items = GetItems();
96+
97+
if (items.Count == 0)
98+
yield break;
99+
100+
var matcher = pattern == "*" ? null : CreateMatcher(pattern);
101+
102+
var enumerator = items.GetEnumerator();
103+
while (enumerator.MoveNext())
104+
{
105+
string key = enumerator.Key as string;
106+
if (key == null)
107+
continue;
108+
if (key.StartsWith(RegionName))
109+
{
110+
key = key.Substring(RegionName.Length);
111+
if (matcher == null || matcher.IsMatch(key))
112+
{
113+
yield return key;
114+
}
115+
}
116+
}
117+
}
118+
119+
private string BuildKey(string key)
120+
{
121+
return RegionName + key.EmptyNull();
122+
}
102123

124+
private static Regex CreateMatcher(string pattern)
125+
{
126+
return new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
127+
}
128+
}
103129
}

src/Libraries/SmartStore.Core/SmartStore.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
<Compile Include="Caching\DefaultCacheManager.cs" />
148148
<Compile Include="Caching\AspNetCache.cs" />
149149
<Compile Include="Caching\DisplayedEntities.cs" />
150+
<Compile Include="Caching\IRequestCache.cs" />
150151
<Compile Include="Caching\IDisplayedEntities.cs" />
151152
<Compile Include="Caching\IOutputCacheProvider.cs" />
152153
<Compile Include="Caching\NullOutputCacheProvider.cs" />

src/Libraries/SmartStore.Services/Catalog/CategoryService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public partial class CategoryService : ICategoryService
4242
private readonly IWorkContext _workContext;
4343
private readonly IStoreContext _storeContext;
4444
private readonly IEventPublisher _eventPublisher;
45-
private readonly ICacheManager _cacheManager;
45+
private readonly IRequestCache _cacheManager;
4646
private readonly IStoreMappingService _storeMappingService;
4747
private readonly IAclService _aclService;
4848
private readonly Lazy<IEnumerable<ICategoryNavigationFilter>> _navigationFilters;
@@ -66,7 +66,7 @@ public partial class CategoryService : ICategoryService
6666
/// <param name="workContext">Work context</param>
6767
/// <param name="storeContext">Store context</param>
6868
/// <param name="eventPublisher">Event publisher</param>
69-
public CategoryService(ICacheManager cacheManager,
69+
public CategoryService(IRequestCache cacheManager,
7070
IRepository<Category> categoryRepository,
7171
IRepository<ProductCategory> productCategoryRepository,
7272
IRepository<Product> productRepository,

src/Libraries/SmartStore.Services/Catalog/CategoryTemplateService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public partial class CategoryTemplateService : ICategoryTemplateService
1818

1919
private readonly IRepository<CategoryTemplate> _categoryTemplateRepository;
2020
private readonly IEventPublisher _eventPublisher;
21-
private readonly ICacheManager _cacheManager;
21+
private readonly IRequestCache _cacheManager;
2222

2323
#endregion
2424

@@ -30,7 +30,7 @@ public partial class CategoryTemplateService : ICategoryTemplateService
3030
/// <param name="cacheManager">Cache manager</param>
3131
/// <param name="categoryTemplateRepository">Category template repository</param>
3232
/// <param name="eventPublisher">Event published</param>
33-
public CategoryTemplateService(ICacheManager cacheManager,
33+
public CategoryTemplateService(IRequestCache cacheManager,
3434
IRepository<CategoryTemplate> categoryTemplateRepository, IEventPublisher eventPublisher)
3535
{
3636
_cacheManager = cacheManager;

src/Libraries/SmartStore.Services/Catalog/ManufacturerService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public partial class ManufacturerService : IManufacturerService
3434
private readonly IWorkContext _workContext;
3535
private readonly IStoreContext _storeContext;
3636
private readonly IEventPublisher _eventPublisher;
37-
private readonly ICacheManager _cacheManager;
37+
private readonly IRequestCache _cacheManager;
3838
#endregion
3939

4040
#region Ctor
@@ -50,7 +50,7 @@ public partial class ManufacturerService : IManufacturerService
5050
/// <param name="workContext">Work context</param>
5151
/// <param name="storeContext">Store context</param>
5252
/// <param name="eventPublisher">Event published</param>
53-
public ManufacturerService(ICacheManager cacheManager,
53+
public ManufacturerService(IRequestCache cacheManager,
5454
IRepository<Manufacturer> manufacturerRepository,
5555
IRepository<ProductManufacturer> productManufacturerRepository,
5656
IRepository<Product> productRepository,

src/Libraries/SmartStore.Services/Catalog/ManufacturerTemplateService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public partial class ManufacturerTemplateService : IManufacturerTemplateService
1818

1919
private readonly IRepository<ManufacturerTemplate> _manufacturerTemplateRepository;
2020
private readonly IEventPublisher _eventPublisher;
21-
private readonly ICacheManager _cacheManager;
21+
private readonly IRequestCache _cacheManager;
2222

2323
#endregion
2424

@@ -30,7 +30,7 @@ public partial class ManufacturerTemplateService : IManufacturerTemplateService
3030
/// <param name="cacheManager">Cache manager</param>
3131
/// <param name="manufacturerTemplateRepository">Manufacturer template repository</param>
3232
/// <param name="eventPublisher">Event published</param>
33-
public ManufacturerTemplateService(ICacheManager cacheManager,
33+
public ManufacturerTemplateService(IRequestCache cacheManager,
3434
IRepository<ManufacturerTemplate> manufacturerTemplateRepository,
3535
IEventPublisher eventPublisher)
3636
{

0 commit comments

Comments
 (0)