Skip to content

Commit 534df1e

Browse files
author
Jeff Treuting
committed
Some refactoring to get rid of some code duplication
Still more needed
1 parent cde6ec3 commit 534df1e

8 files changed

+304
-445
lines changed

SharpRepository.Repository/Caching/CompoundKeyCachingStrategyBase.cs

Lines changed: 6 additions & 328 deletions
Large diffs are not rendered by default.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq.Expressions;
4+
using SharpRepository.Repository.Queries;
5+
using SharpRepository.Repository.Specifications;
6+
7+
namespace SharpRepository.Repository.Caching
8+
{
9+
public abstract class CompoundKeyCachingStrategyCommon<T> where T : class
10+
{
11+
private ICachingProvider _cachingProvider;
12+
public string CachePrefix { get; set; }
13+
protected string TypeFullName { get; set; }
14+
15+
public ICachingProvider CachingProvider
16+
{
17+
get { return _cachingProvider; }
18+
set { _cachingProvider = value ?? new InMemoryCachingProvider(); }
19+
}
20+
21+
internal CompoundKeyCachingStrategyCommon() { }
22+
23+
internal CompoundKeyCachingStrategyCommon(ICachingProvider cachingProvider)
24+
{
25+
CachePrefix = "#Repo";
26+
CachingProvider = cachingProvider;
27+
28+
TypeFullName = typeof(T).FullName ?? typeof(T).Name; // sometimes FullName returns null in certain derived type situations, so I added the check to use the Name property if FullName is null
29+
}
30+
31+
public virtual bool TryGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out IEnumerable<TResult> result)
32+
{
33+
var cacheKey = GetAllCacheKey(queryOptions, selector);
34+
if (!IsInCache(cacheKey, out result))
35+
return false;
36+
37+
// if there are no query options then we don't need to check for the cache for data to update them with
38+
return queryOptions == null || SetCachedQueryOptions(cacheKey, queryOptions);
39+
}
40+
41+
public virtual void SaveGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, IEnumerable<TResult> result)
42+
{
43+
SetCache(GetAllCacheKey(queryOptions, selector), result, queryOptions);
44+
}
45+
46+
public virtual bool TryFindAllResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out IEnumerable<TResult> result)
47+
{
48+
var cacheKey = FindAllCacheKey(criteria, queryOptions, selector);
49+
if (!IsInCache(cacheKey, out result))
50+
return false;
51+
52+
// if there are no query options then we don't need to check for the cache for data to update them with
53+
return queryOptions == null || SetCachedQueryOptions(cacheKey, queryOptions);
54+
}
55+
56+
public virtual void SaveFindAllResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, IEnumerable<TResult> result)
57+
{
58+
SetCache(FindAllCacheKey(criteria, queryOptions, selector), result, queryOptions);
59+
}
60+
61+
public virtual bool TryFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out TResult result)
62+
{
63+
return IsInCache(FindCacheKey(criteria, queryOptions, selector), out result);
64+
}
65+
66+
public virtual void SaveFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, TResult result)
67+
{
68+
SetCache(FindCacheKey(criteria, queryOptions, selector), result);
69+
}
70+
71+
public abstract void Save();
72+
73+
protected bool IsInCache<TCacheItem>(string cacheKey, out TCacheItem result)
74+
{
75+
result = default(TCacheItem);
76+
77+
try
78+
{
79+
if (CachingProvider.Get(cacheKey, out result))
80+
{
81+
return true;
82+
}
83+
}
84+
catch (Exception)
85+
{
86+
// don't let caching errors cause problems for the Repository
87+
}
88+
89+
return false;
90+
}
91+
92+
protected bool IsPagingTotalInCache(string cacheKey, out int totalItems)
93+
{
94+
totalItems = 0;
95+
try
96+
{
97+
if (CachingProvider.Get(cacheKey + "=>pagingTotal", out totalItems))
98+
{
99+
//Trace.WriteLine(String.Format("Got item from cache: {0} - {1}", cacheKey, typeof(TCacheItem).Name));
100+
return true;
101+
}
102+
}
103+
catch (Exception)
104+
{
105+
// don't let caching errors cause problems for the Repository
106+
}
107+
108+
return false;
109+
}
110+
111+
/// <summary>
112+
/// This will repopualte the PagingOptions.TotalItems from the value stored in cache. This should only be called if the results were already found in cache.
113+
/// </summary>
114+
/// <param name="cacheKey"></param>
115+
/// <param name="queryOptions"></param>
116+
/// <returns>True if it is not a PagingOptions query or if it is and the TotalItems is stored in cache as well</returns>
117+
protected bool SetCachedQueryOptions(string cacheKey, IQueryOptions<T> queryOptions)
118+
{
119+
// TODO: see if there is a better way that doesn't rely on checking for PagingOptions specifically
120+
// originally was thinking doing a ref arg for queryOptions and setting it via cache but ran into an issue in QueryManager using a ref in a lamda expression
121+
122+
// we only need to do this for PagingOptions because it has a TotalItems property that we need
123+
if (!(queryOptions is PagingOptions<T>))
124+
return true;
125+
126+
int totalItems;
127+
// there is a PagingOptions passed in so we want to make sure that both the results and the queryOptions are in cache
128+
// this is a safety in case the caching provider kicked one of them out
129+
if (IsPagingTotalInCache(cacheKey, out totalItems))
130+
{
131+
((PagingOptions<T>)queryOptions).TotalItems = totalItems;
132+
return true;
133+
}
134+
135+
// this was a PagingOptions query but the value wasn't in cache, so return false which will make the entire query be ran again so the results and TotalItems will get cached
136+
return false;
137+
}
138+
139+
protected void ClearCache(string cacheKey)
140+
{
141+
try
142+
{
143+
CachingProvider.Clear(cacheKey);
144+
}
145+
catch (Exception)
146+
{
147+
// don't let caching errors mess with the repository
148+
}
149+
}
150+
151+
protected void SetCache<TCacheItem>(string cacheKey, TCacheItem result, IQueryOptions<T> queryOptions = null)
152+
{
153+
try
154+
{
155+
CachingProvider.Set(cacheKey, result);
156+
157+
if (queryOptions is PagingOptions<T>)
158+
{
159+
CachingProvider.Set(cacheKey + "=>pagingTotal", ((PagingOptions<T>)queryOptions).TotalItems);
160+
}
161+
//Trace.WriteLine(String.Format("Write item to cache: {0} - {1}", cacheKey, typeof(TCacheItem).Name));
162+
}
163+
catch (Exception)
164+
{
165+
// don't let caching errors mess with the repository
166+
}
167+
}
168+
169+
protected abstract string GetAllCacheKey<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector);
170+
171+
protected abstract string FindAllCacheKey<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector);
172+
173+
protected abstract string FindCacheKey<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector);
174+
175+
protected string GetWriteThroughCacheKey<TResult>(object[] keys, Expression<Func<T, TResult>> selector)
176+
{
177+
return String.Format("{0}/{1}/{2}::{3}", CachePrefix, TypeFullName, String.Join("/", keys), (selector != null ? selector.ToString() : "null"));
178+
}
179+
}
180+
}

SharpRepository.Repository/Caching/ICompoundKeyCachingStrategy.cs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@
66

77
namespace SharpRepository.Repository.Caching
88
{
9-
public interface ICompoundKeyCachingStrategy<T>
9+
public interface ICompoundKeyCachingStrategyBase<T>
1010
{
11-
bool TryGetResult<TResult>(object[] keys, Expression<Func<T, TResult>> selector, out TResult result);
12-
void SaveGetResult<TResult>(object[] keys, Expression<Func<T, TResult>> selector, TResult result);
13-
1411
bool TryGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out IEnumerable<TResult> result);
1512
void SaveGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, IEnumerable<TResult> result);
1613

@@ -20,33 +17,28 @@ public interface ICompoundKeyCachingStrategy<T>
2017
bool TryFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out TResult result);
2118
void SaveFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, TResult result);
2219

23-
void Add(object[] keys, T result);
24-
void Update(object[] keys, T result);
25-
void Delete(object[] keys, T result);
2620
void Save();
2721

2822
ICachingProvider CachingProvider { get; set; }
2923
}
3024

31-
public interface ICompoundKeyCachingStrategy<T, TKey, TKey2>
25+
public interface ICompoundKeyCachingStrategy<T> : ICompoundKeyCachingStrategyBase<T>
3226
{
33-
bool TryGetResult<TResult>(TKey key, TKey2 key2, Expression<Func<T, TResult>> selector, out TResult result);
34-
void SaveGetResult<TResult>(TKey key, TKey2 key2, Expression<Func<T, TResult>> selector, TResult result);
35-
36-
bool TryGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out IEnumerable<TResult> result);
37-
void SaveGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, IEnumerable<TResult> result);
27+
bool TryGetResult<TResult>(object[] keys, Expression<Func<T, TResult>> selector, out TResult result);
28+
void SaveGetResult<TResult>(object[] keys, Expression<Func<T, TResult>> selector, TResult result);
3829

39-
bool TryFindAllResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out IEnumerable<TResult> result);
40-
void SaveFindAllResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, IEnumerable<TResult> result);
30+
void Add(object[] keys, T result);
31+
void Update(object[] keys, T result);
32+
void Delete(object[] keys, T result);
33+
}
4134

42-
bool TryFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out TResult result);
43-
void SaveFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, TResult result);
35+
public interface ICompoundKeyCachingStrategy<T, TKey, TKey2> : ICompoundKeyCachingStrategyBase<T>
36+
{
37+
bool TryGetResult<TResult>(TKey key, TKey2 key2, Expression<Func<T, TResult>> selector, out TResult result);
38+
void SaveGetResult<TResult>(TKey key, TKey2 key2, Expression<Func<T, TResult>> selector, TResult result);
4439

4540
void Add(TKey key, TKey2 key2, T result);
4641
void Update(TKey key, TKey2 key2, T result);
4742
void Delete(TKey key, TKey2 key2, T result);
48-
void Save();
49-
50-
ICachingProvider CachingProvider { get; set; }
5143
}
5244
}
Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq.Expressions;
4-
using SharpRepository.Repository.Queries;
5-
using SharpRepository.Repository.Specifications;
6-
1+

72
namespace SharpRepository.Repository.Caching
83
{
94
/// <summary>
@@ -35,77 +30,4 @@ public class NoCachingStrategy<T> : NoCachingStrategyBase<T, int>
3530
{
3631

3732
}
38-
39-
public class NoCompoundKeyCachingStrategy<T> : ICompoundKeyCachingStrategy<T>
40-
{
41-
internal NoCompoundKeyCachingStrategy()
42-
{
43-
}
44-
45-
public bool TryGetResult<TResult>(object[] keys, Expression<Func<T, TResult>> selector, out TResult result)
46-
{
47-
result = default(TResult);
48-
return false;
49-
}
50-
51-
public void SaveGetResult<TResult>(object[] keys, Expression<Func<T, TResult>> selector, TResult result)
52-
{
53-
54-
}
55-
56-
public bool TryGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out IEnumerable<TResult> result)
57-
{
58-
result = default(IEnumerable<TResult>);
59-
return false;
60-
}
61-
62-
public void SaveGetAllResult<TResult>(IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, IEnumerable<TResult> result)
63-
{
64-
65-
}
66-
67-
public bool TryFindAllResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out IEnumerable<TResult> result)
68-
{
69-
result = default(IEnumerable<TResult>);
70-
return false;
71-
}
72-
73-
public void SaveFindAllResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, IEnumerable<TResult> result)
74-
{
75-
76-
}
77-
78-
public bool TryFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, out TResult result)
79-
{
80-
result = default(TResult);
81-
return false;
82-
}
83-
84-
public void SaveFindResult<TResult>(ISpecification<T> criteria, IQueryOptions<T> queryOptions, Expression<Func<T, TResult>> selector, TResult result)
85-
{
86-
87-
}
88-
89-
public void Add(object[] keys, T result)
90-
{
91-
92-
}
93-
94-
public void Update(object[] keys, T result)
95-
{
96-
97-
}
98-
99-
public void Delete(object[] keys, T result)
100-
{
101-
102-
}
103-
104-
public void Save()
105-
{
106-
107-
}
108-
109-
public ICachingProvider CachingProvider { get; set; }
110-
}
11133
}

0 commit comments

Comments
 (0)