Skip to content
Browse files

Working on caching proxy updater

updated the cache disabler
  • Loading branch information...
1 parent 9e1e2bb commit cd0d841d50f86fccf2ebd896283babbe16f26e64 @gravypower gravypower committed Jan 17, 2013
Showing with 501 additions and 209 deletions.
  1. +5 −0 Sites/Sitecore/Glass.Mapper.Sites.Sc/Glass.Mapper.Sites.Sc.ncrunchproject
  2. +0 −6 Sites/Sitecore/Glass.Mapper.Sites.Sc/layouts/TestSub.ascx.cs
  3. +0 −2 Source/Glass.Mapper.Sc/GlassConfig.cs
  4. +10 −45 Source/Glass.Mapper/AbstractService.cs
  5. +0 −2 Source/Glass.Mapper/AbstractTypeCreationContext.cs
  6. +47 −13 Source/Glass.Mapper/Caching/CacheDisabler.cs
  7. +6 −0 Source/Glass.Mapper/Caching/CacheKeyResolving/CacheKey.cs
  8. +1 −0 Source/Glass.Mapper/Caching/CacheKeyResolving/ICacheKey.cs
  9. +25 −3 Source/Glass.Mapper/Caching/ObjectCaching/AbstractObjectCache.cs
  10. +109 −30 Source/Glass.Mapper/Caching/ObjectCaching/CacheInformation.cs
  11. +6 −0 Source/Glass.Mapper/Caching/ObjectCaching/IAbstractObjectCache.cs
  12. +49 −0 Source/Glass.Mapper/Caching/Proxy/CacheLazyObjectInterceptor.cs
  13. +34 −8 Source/Glass.Mapper/Caching/Proxy/CacheMethodInterceptor.cs
  14. +7 −17 Source/Glass.Mapper/Caching/Proxy/CacheProxyGenerator.cs
  15. +1 −4 Source/Glass.Mapper/Caching/Proxy/CacheProxyGeneratorHook.cs
  16. +1 −1 Source/Glass.Mapper/Configuration/AbstractObjectCacheConfiguration.cs
  17. +10 −2 Source/Glass.Mapper/Context.cs
  18. +3 −2 Source/Glass.Mapper/Glass.Mapper.csproj
  19. +1 −4 Source/Glass.Mapper/{Caching → ObjectCaching}/Proxy/CacheInterfaceMethodInterceptor.cs
  20. +4 −5 Source/Glass.Mapper/Pipelines/ObjectConstruction/ObjectConstructionArgs.cs
  21. +2 −1 Source/Glass.Mapper/Pipelines/ObjectConstruction/Tasks/CreateConcrete/CreateConcreteTask.cs
  22. +5 −1 Source/Glass.Mapper/Pipelines/ObjectConstruction/Tasks/CreateConcrete/LazyObjectInterceptor.cs
  23. +6 −1 Source/Glass.Mapper/Pipelines/ObjectConstruction/Tasks/CreateInterface/CreateInterfaceTask.cs
  24. +3 −2 ...lass.Mapper/Pipelines/ObjectConstruction/Tasks/ObjectCachingResolver/ObjectCachingResolverTask.cs
  25. +3 −3 Source/Glass.Mapper/Pipelines/ObjectConstruction/Tasks/ObjectCachingSaver/ObjectCachingSaverTask.cs
  26. +38 −38 Tests/Integration Tests/Sitecore/Glass.Mapper.Sc.Integration/SetupSitecoreForTesting.cs
  27. +74 −19 Tests/Unit Tests/Glass.Mapper.Tests/Caching/CacheInformationFixture.cs
  28. +50 −0 Tests/Unit Tests/Glass.Mapper.Tests/Caching/ProxiesFixture.cs
  29. +1 −0 Tests/Unit Tests/Glass.Mapper.Tests/Glass.Mapper.Tests.csproj
View
5 Sites/Sitecore/Glass.Mapper.Sites.Sc/Glass.Mapper.Sites.Sc.ncrunchproject
@@ -17,4 +17,9 @@
<UseBuildPlatform></UseBuildPlatform>
<ProxyProcessPath></ProxyProcessPath>
<UseCPUArchitecture>AutoDetect</UseCPUArchitecture>
+ <IgnoredTests>
+ <RegexTestSelector>
+ <RegularExpression>.*</RegularExpression>
+ </RegexTestSelector>
+ </IgnoredTests>
</ProjectConfiguration>
View
6 Sites/Sitecore/Glass.Mapper.Sites.Sc/layouts/TestSub.ascx.cs
@@ -1,12 +1,6 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Web;
-using System.Web.UI;
-using System.Web.UI.WebControls;
using Glass.Mapper.Sc;
using Glass.Mapper.Sc.Configuration.Attributes;
-using Glass.Mapper.Sc.Integration;
using Glass.Mapper.Sites.Sc.Models;
namespace Glass.Mapper.Sites.Sc.layouts
View
2 Source/Glass.Mapper.Sc/GlassConfig.cs
@@ -142,8 +142,6 @@ public override void Configure(WindsorContainer container, string contextName)
Component.For<IObjectSavingTask>().ImplementedBy<StandardSavingTask>().LifestyleTransient(),
-
-
Component.For<AbstractObjectCacheConfiguration>().ImplementedBy<ObjectCacheConfiguration>().LifestyleTransient(),
Component.For<IAbstractObjectCache>().ImplementedBy<CacheTable<Guid>>().LifestyleTransient(),
Component.For<AbstractCacheKeyResolver<Guid>>().ImplementedBy<SitecoreCacheKeyResolver>().LifestyleTransient()
View
55 Source/Glass.Mapper/AbstractService.cs
@@ -16,18 +16,8 @@ namespace Glass.Mapper
{
public abstract class AbstractService : IAbstractService
{
-
private IPerformanceProfiler _profiler;
- /// <summary>
- /// The list of tasks to be performed by the Object Construction Pipeline. Called in the order specified.
- /// </summary>
- private IEnumerable<IObjectConstructionTask> ObjectConstructionTasks { get; set; }
-
- /// <summary>
- /// The list of tasks to be performed by the Object Construction Pipeline. Called in the order specified.
- /// </summary>
- private IEnumerable<ObjectConstructionTask> ObjectConstructionTasks { get; set; }
public IPerformanceProfiler Profiler
{
get { return _profiler; }
@@ -41,9 +31,7 @@ public IPerformanceProfiler Profiler
}
}
- public Context GlassContext { get; private set; }
-
-
+ public Context GlassContext { get; private set; }
private TypeResolver _typeResolver;
@@ -52,7 +40,7 @@ public IPerformanceProfiler Profiler
private ObjectConstruction _objectConstruction;
private ObjectSaving _objectSaving;
-
+
public AbstractService()
: this(Context.Default)
{
@@ -69,17 +57,11 @@ public AbstractService(Context glassContext)
GlassContext = glassContext;
- if (GlassContext == null)
+ if (GlassContext == null)
throw new NullReferenceException("Context is null");
-
- ObjectConstructionTasks = glassContext.DependencyResolver.ResolveAllInOrder<ObjectConstructionTask>("Order");
- TypeResolverTasks = glassContext.DependencyResolver.ResolveAll<ITypeResolverTask>();
- ConfigurationResolverTasks = glassContext.DependencyResolver.ResolveAll<IConfigurationResolverTask>();
- ObjectSavingTasks = glassContext.DependencyResolver.ResolveAll<IObjectSavingTask>();
-
- var objectConstructionTasks = glassContext.DependencyResolver.ResolveAll<IObjectConstructionTask>();
- _objectConstruction = new ObjectConstruction(objectConstructionTasks);
+ var objectConstructionTasks = glassContext.DependencyResolver.ResolveAllInOrder<ObjectConstructionTask>("Order");
+ _objectConstruction = new ObjectConstruction(objectConstructionTasks);
var typeResolverTasks = glassContext.DependencyResolver.ResolveAll<ITypeResolverTask>();
_typeResolver = new TypeResolver(typeResolverTasks);
@@ -107,28 +89,17 @@ public object InstantiateObject(AbstractTypeCreationContext abstractTypeCreation
//run the pipeline to get the configuration to load
var configurationArgs = new ConfigurationResolverArgs(GlassContext, abstractTypeCreationContext, typeArgs.Result);
_configurationResolver.Run(configurationArgs);
-
+
if (configurationArgs.Result == null)
throw new NullReferenceException("Configuration Resolver pipeline did not return type.");
var config = configurationArgs.Result;
//Run the object construction
- _objectConstruction.Run(objectArgs);
+ var objectArgs = new ObjectConstructionArgs(GlassContext, abstractTypeCreationContext, config, this);
- var objectArgs = new ObjectConstructionArgs(GlassContext, abstractTypeCreationContext,
- config, this);
- if (DisableCache)
- {
- using (new CacheDisabler(objectArgs))
- {
- objectRunner.Run(objectArgs);
- }
- }
- else
- {
- objectRunner.Run(objectArgs);
- }
+
+ _objectConstruction.Run(objectArgs);
return objectArgs.Result;
@@ -157,17 +128,13 @@ public void SaveObject(AbstractTypeSavingContext abstractTypeSavingContext)
/// <param name="obj"></param>
/// <returns></returns>
public abstract AbstractDataMappingContext CreateDataMappingContext(AbstractTypeSavingContext creationContext);
-
-
- public bool DisableCache { get; set; }
}
public interface IAbstractService
{
- Context GlassContext { get; }
+ Context GlassContext { get; }
object InstantiateObject(AbstractTypeCreationContext abstractTypeCreationContext);
-
/// <summary>
/// Used to create the context used by DataMappers to map data to a class
/// </summary>
@@ -183,7 +150,5 @@ public interface IAbstractService
/// <param name="creationContext">The Saving Context</param>
/// <returns></returns>
AbstractDataMappingContext CreateDataMappingContext(AbstractTypeSavingContext creationContext);
-
- bool DisableCache { get; set; }
}
}
View
2 Source/Glass.Mapper/AbstractTypeCreationContext.cs
@@ -12,8 +12,6 @@ namespace Glass.Mapper
/// </summary>
public abstract class AbstractTypeCreationContext
{
-
-
public bool InferType { get; set; }
public bool IsLazy { get; set; }
public Type RequestedType { get; set; }
View
60 Source/Glass.Mapper/Caching/CacheDisabler.cs
@@ -1,32 +1,66 @@
using System;
+using System.Web;
using Glass.Mapper.Pipelines.ObjectConstruction;
namespace Glass.Mapper.Caching
{
public class CacheDisabler:IDisposable
{
- private readonly ObjectConstructionArgs _args;
- private readonly IAbstractService _abstractService;
- public CacheDisabler(ObjectConstructionArgs args)
+ public static bool CacheDisabled
{
- this._args = args;
- args.DisableCache = true;
+ get
+ {
+ return HttpContext.Current != null ? ReturnFromHttpContxt() : ReturnFromThreadStatic();
+ }
+ set
+ {
+ if (HttpContext.Current != null)
+ {
+ SetToHttpContext(value);
+ }
+
+ SetToThreadStatic(value);
+ }
}
- public CacheDisabler(IAbstractService abstractService)
+ private static void SetToHttpContext(bool value)
{
- this._abstractService = abstractService;
- _abstractService.DisableCache = true;
+ HttpContext.Current.Items["Glass_CacheDisabled"] = value;
}
- public void Dispose()
+ private static bool ReturnFromHttpContxt()
+ {
+ if (HttpContext.Current.Items.Contains("Glass_CacheDisabled"))
+ {
+ {
+ return (bool)HttpContext.Current.Items["Glass_CacheDisabled"];
+ }
+ }
+ return false;
+ }
+
+ [ThreadStatic]
+ private static bool _threadStaticCacheDisabled;
+
+ private static void SetToThreadStatic(bool value)
{
- if(_args != null)
- _args.DisableCache = false;
+ _threadStaticCacheDisabled = value;
+ }
- if(_abstractService != null)
- _abstractService.DisableCache = false;
+ private static bool ReturnFromThreadStatic()
+ {
+ return _threadStaticCacheDisabled;
+ }
+
+ public CacheDisabler()
+ {
+ CacheDisabled = true;
+ }
+
+ public void Dispose()
+ {
+ CacheDisabled = false;
}
}
}
View
6 Source/Glass.Mapper/Caching/CacheKeyResolving/CacheKey.cs
@@ -28,5 +28,11 @@ public override string ToString()
}
public abstract bool Equals(CacheKey<TIdType> other);
+
+
+ public object GetId()
+ {
+ return Id;
+ }
}
}
View
1 Source/Glass.Mapper/Caching/CacheKeyResolving/ICacheKey.cs
@@ -3,5 +3,6 @@
public interface ICacheKey
{
bool Equals(object other);
+ object GetId();
}
}
View
28 Source/Glass.Mapper/Caching/ObjectCaching/AbstractObjectCache.cs
@@ -3,16 +3,18 @@
using System.Threading;
using Glass.Mapper.Caching.CacheKeyResolving;
using Glass.Mapper.Caching.ObjectCaching.Exceptions;
+using Glass.Mapper.Caching.Proxy;
using Glass.Mapper.Pipelines.ObjectConstruction;
using System.Linq;
namespace Glass.Mapper.Caching.ObjectCaching
{
public abstract class AbstractObjectCache<TIdType> : IAbstractObjectCache
{
- private readonly CacheInformation _cacheInformation = new CacheInformation();
+ private readonly CacheInformation<TIdType> _cacheInformation = new CacheInformation<TIdType>();
public string BaseCacheKey { get; set; }
-
+
+
public string DefaultBaseCacheKey
{
get { return "GlassObjectCahe"; }
@@ -26,7 +28,6 @@ public string DefaultBaseCacheKey
protected abstract void InternalAddObject(string objectKey, object objectForCaching);
protected abstract bool InternalClearCache();
-
protected AbstractObjectCache(string baseCacheKey)
{
BaseCacheKey = baseCacheKey;
@@ -64,6 +65,21 @@ public void AddObject(ObjectConstructionArgs args)
InternalAddObject(CacheKeyResolver.GetKey(args).ToString(), args.Result);
}
+ public object GetObject(ICacheKey cacheKey)
+ {
+ return InternalGetObject(cacheKey.ToString());
+ }
+
+ public bool ContansObject(ICacheKey cacheKey)
+ {
+ return InternalContansObject(cacheKey.ToString());
+ }
+
+ public void AddObject(ICacheKey cacheKey, object objectForCaching)
+ {
+ InternalAddObject(cacheKey.ToString(), objectForCaching);
+ }
+
public bool ClearCache()
{
return InternalClearCache();
@@ -181,5 +197,11 @@ public bool RemoveFromRelatedCache(string releatedKey)
return InternalRemoveObject(releatedKey);
}
+
+
+ public ICacheKey GetLatestCacheKey(object id)
+ {
+ return _cacheInformation.GetCacheKeys((TIdType)id).Peek();
+ }
}
}
View
139 Source/Glass.Mapper/Caching/ObjectCaching/CacheInformation.cs
@@ -1,27 +1,32 @@
-using System;
+using Glass.Mapper.Caching.CacheKeyResolving;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Glass.Mapper.Caching.ObjectCaching
{
- public class CacheInformation
+ public class CacheInformation<TIdType>
{
private readonly int _timeout = 10000;
- private readonly ReaderWriterLockSlim _readerWriterLock = new ReaderWriterLockSlim();
+ private readonly ReaderWriterLockSlim _readerWriterLockRelatedKeys = new ReaderWriterLockSlim();
+ private readonly ReaderWriterLockSlim _readerWriterLockCacheKey = new ReaderWriterLockSlim();
private volatile Dictionary<string, List<string>> _relatedKeys;
private volatile List<string> _objectKeys;
private volatile Dictionary<string, List<string>> _objectKeysRelatedKeys;
+ private volatile Dictionary<TIdType, Stack<CacheKey<TIdType>>> _idToCacheKey;
+
public CacheInformation()
{
_relatedKeys = new Dictionary<string, List<string>>();
_objectKeysRelatedKeys = new Dictionary<string, List<string>>();
_objectKeys = new List<string>();
+ _idToCacheKey = new Dictionary<TIdType, Stack<CacheKey<TIdType>>>();
}
public CacheInformation(int timeout)
@@ -30,41 +35,110 @@ public CacheInformation(int timeout)
_timeout = timeout;
}
+ public Stack<CacheKey<TIdType>> GetCacheKeys(TIdType id)
+ {
+ using (var rel = new ReaderWriterLock(_readerWriterLockCacheKey, ReaderWriterLockType.Reader, _timeout))
+ {
+ if (rel.HasTakenLock)
+ {
+ return GetCacheKeysKvp(id).Value;
+ }
+ }
+ //TODO: create an exception type
+ throw new Exception("Could not take lock");
+ }
- public void AddRelatedKey(string releatedKey)
+ public void AddCacheKey(TIdType id, CacheKey<TIdType> cacheKey)
+ {
+ using (var rel = new ReaderWriterLock(_readerWriterLockCacheKey, ReaderWriterLockType.Writer, _timeout))
+ {
+ if (!rel.HasTakenLock) return;
+ InternalAddCacheKey(id, cacheKey);
+ }
+ }
+
+ private void InternalAddCacheKey(TIdType id, CacheKey<TIdType> cacheKey)
{
- if (!ContainsRepeatedKey(releatedKey))
+ if (!ContainsCacheKey(id))
{
- InternalAddRepeatedKey(releatedKey);
+ _idToCacheKey.Add(id, new Stack<CacheKey<TIdType>>());
+ }
+
+ if (!_idToCacheKey[id].Contains(cacheKey))
+ {
+ _idToCacheKey[id].Push(cacheKey);
}
}
- private void InternalAddRepeatedKey(string relatedKey)
+ public bool ContainsCacheKey(TIdType id, CacheKey<TIdType> cacheKey)
{
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockCacheKey, ReaderWriterLockType.Reader, _timeout))
{
if (rel.HasTakenLock)
{
- _relatedKeys.Add(relatedKey, new List<string>());
+ return ContainsCacheKey(id) && GetCacheKeysKvp(id).Value.Any(x => x == cacheKey);
}
}
+ //TODO: create an exception type
+ throw new Exception("Could not take lock");
}
- private bool ContainsRepeatedKey(string releatedKey)
+ public bool ContainsCacheKey(CacheKey<TIdType> cacheKey, List<CacheKey<TIdType>> cacheKeys)
{
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Reader, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockCacheKey, ReaderWriterLockType.Reader, _timeout))
{
if (rel.HasTakenLock)
{
- return _relatedKeys.ContainsKey(releatedKey);
+ return cacheKeys.Contains(cacheKey);
+ }
+ }
+ //TODO: create an exception type
+ throw new Exception("Could not take lock");
+ }
+
+ private bool ContainsCacheKey(TIdType id)
+ {
+ return !GetCacheKeysKvp(id).Equals(default(KeyValuePair<TIdType, Stack<CacheKey<TIdType>>>));
+ }
+
+ private KeyValuePair<TIdType, Stack<CacheKey<TIdType>>> GetCacheKeysKvp(TIdType id)
+ {
+ return GetCacheKeys().SingleOrDefault(x => x.Key.Equals(id));
+ }
+
+ private Dictionary<TIdType, Stack<CacheKey<TIdType>>> GetCacheKeys()
+ {
+ return CloneDictionary(_idToCacheKey);;
+ }
+
+ public void AddRelatedKey(string releatedKey)
+ {
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
+ {
+ if (rel.HasTakenLock)
+ {
+ if (!ContainsRelatedKey(releatedKey))
+ {
+ InternalAddRelatedKey(releatedKey);
+ }
+ }
+ }
+ }
+
+ private void InternalAddRelatedKey(string relatedKey)
+ {
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
+ {
+ if (rel.HasTakenLock)
+ {
+ _relatedKeys.Add(relatedKey, new List<string>());
}
}
- return false;
}
private void AddRelatedKayAndObjectKey(string releatedKey, string objectKey)
{
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
{
if (rel.HasTakenLock)
{
@@ -87,9 +161,9 @@ private void AddRelatedKayAndObjectKey(string releatedKey, string objectKey)
public void AddObjectKey(string releatedKey, string objectKey)
{
- if (ContainsRepeatedKey(releatedKey))
+ if (ContainsRelatedKey(releatedKey))
{
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
{
if (rel.HasTakenLock)
{
@@ -118,7 +192,7 @@ public void AddObjectKey(string releatedKey, string objectKey)
public System.Collections.ICollection GetRelatedKeys()
{
var keyList = new List<string>();
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Reader, _timeout))
{
if (rel.HasTakenLock)
{
@@ -129,17 +203,22 @@ public System.Collections.ICollection GetRelatedKeys()
return keyList;
}
- private List<string> CloneList(IEnumerable<string> list)
+ private List<T> CloneList<T>(IEnumerable<T> list)
+ {
+ return new List<T>(list);
+ }
+
+ private Dictionary<T, K> CloneDictionary<T, K>(IDictionary<T, K> dictionary)
{
- return new List<string>(list);
+ return new Dictionary<T, K>(dictionary);
}
public System.Collections.ICollection Keys
{
get
{
var returnKeyList = new List<string>();
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
{
if (rel.HasTakenLock)
{
@@ -163,13 +242,13 @@ public bool ContainsRelatedKey(string releatedKey)
public void AddObjectKey(IEnumerable<string> releatedKeys, string objectKey)
{
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
{
if (!rel.HasTakenLock) return;
foreach (var releatedKey in releatedKeys)
{
- if (ContainsRepeatedKey(releatedKey))
+ if (ContainsRelatedKey(releatedKey))
{
if (!_relatedKeys.ContainsKey(releatedKey))
{
@@ -197,9 +276,9 @@ public void AddObjectKey(IEnumerable<string> releatedKeys, string objectKey)
public System.Collections.ICollection GetObjectKeys(string releatedKey)
{
List<string> returnList;
- using (new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
{
- returnList = new List<string>(_relatedKeys[releatedKey]);
+ returnList = CloneList(_relatedKeys[releatedKey]);
}
return returnList;
@@ -211,7 +290,7 @@ public System.Collections.ICollection GetObjectKeys(string releatedKey)
/// <param name="objectKey">The object key.</param>
public void RemoveObjectKey(string objectKey)
{
- using (var rel = new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (var rel = new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
{
_objectKeys.Remove(objectKey);
@@ -224,13 +303,13 @@ public void RemoveObjectKey(string objectKey)
_objectKeysRelatedKeys[objectKey].RemoveAll(x => x == relatedKey);
}
- if (this._relatedKeys.ContainsKey(relatedKey))
+ if (_relatedKeys.ContainsKey(relatedKey))
{
- this._relatedKeys[relatedKey].RemoveAll(x => x == objectKey);
+ _relatedKeys[relatedKey].RemoveAll(x => x == objectKey);
}
- if (!this._relatedKeys[relatedKey].Any())
- this._relatedKeys.Remove(relatedKey);
+ if (!_relatedKeys[relatedKey].Any())
+ _relatedKeys.Remove(relatedKey);
}
@@ -240,7 +319,7 @@ public void RemoveObjectKey(string objectKey)
public void RemoveRelatedKey(string relatedKey)
{
- using (new ReaderWriterLock(_readerWriterLock, ReaderWriterLockType.Writer, _timeout))
+ using (new ReaderWriterLock(_readerWriterLockRelatedKeys, ReaderWriterLockType.Writer, _timeout))
{
foreach (var objectKey in _relatedKeys[relatedKey])
{
View
6 Source/Glass.Mapper/Caching/ObjectCaching/IAbstractObjectCache.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Glass.Mapper.Caching.CacheKeyResolving;
using Glass.Mapper.Pipelines.ObjectConstruction;
namespace Glass.Mapper.Caching.ObjectCaching
@@ -10,6 +11,9 @@ public interface IAbstractObjectCache
object GetObject(ObjectConstructionArgs args);
bool ContansObject(ObjectConstructionArgs args);
void AddObject(ObjectConstructionArgs args);
+ object GetObject(ICacheKey cacheKey);
+ bool ContansObject(ICacheKey cacheKey);
+ void AddObject(ICacheKey cacheKey, object objectForCaching);
bool ClearCache();
object GetFromRelatedCache<T>(string objectKey);
@@ -19,5 +23,7 @@ public interface IAbstractObjectCache
bool ClearRelatedCache(string releatedKey);
bool RemoveFromRelatedCache(string releatedKey);
IDictionary<string, List<string>> GetRelatedKeys();
+
+ ICacheKey GetLatestCacheKey(object id);
}
}
View
49 Source/Glass.Mapper/Caching/Proxy/CacheLazyObjectInterceptor.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Castle.DynamicProxy;
+using Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete;
+
+namespace Glass.Mapper.Caching.Proxy
+{
+ public class CacheLazyObjectInterceptor: IInterceptor
+ {
+ Dictionary<string, object> _values = new Dictionary<string, object>();
+
+ LazyObjectInterceptor _subInterceptor;
+
+ public CacheLazyObjectInterceptor(LazyObjectInterceptor subInterceptor)
+ {
+ _subInterceptor = subInterceptor;
+ }
+
+ public void Intercept(Castle.DynamicProxy.IInvocation invocation)
+ {
+
+ if (invocation.Method.IsSpecialName)
+ {
+ if (invocation.Method.Name.StartsWith("get_") || invocation.Method.Name.StartsWith("set_"))
+ {
+
+ string method = invocation.Method.Name.Substring(0, 4);
+ string name = invocation.Method.Name.Substring(4);
+
+ if (method == "get_" && _values.ContainsKey(name))
+ {
+ invocation.ReturnValue = _values[name];
+ return;
+ }
+ else if (method == "set_")
+ {
+ _values[name] = invocation.Arguments[0];
+ return;
+ }
+ }
+
+ }
+
+ _subInterceptor.Intercept(invocation);
+ }
+ }
+}
View
42 Source/Glass.Mapper/Caching/Proxy/CacheMethodInterceptor.cs
@@ -1,27 +1,53 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using Castle.DynamicProxy;
-using Glass.Mapper.Configuration;
+using Glass.Mapper.Caching.CacheKeyResolving;
+using Glass.Mapper.Caching.ObjectCaching;
+using Glass.Mapper.Pipelines.ObjectConstruction;
-namespace Glass.Mapper.ObjectCaching.Proxy
+namespace Glass.Mapper.Caching.Proxy
{
public class CacheMethodInterceptor : IInterceptor
{
- private readonly Dictionary<string, object> _values;
- private readonly object _originalTarget;
+ private Dictionary<string, object> _values;
+ private object _originalTarget;
+ private ICacheKey _cacheKey;
- public CacheMethodInterceptor(object originalTarget)
+ public static DateTime LastUpdated { get; set; }
+
+ private DateTime _lastUpdated;
+
+
+ static CacheMethodInterceptor()
+ {
+ LastUpdated = DateTime.Now;
+ }
+
+ public CacheMethodInterceptor(object originalTarget, ObjectConstructionArgs args)
{
_values = new Dictionary<string, object>();
- _originalTarget = originalTarget;
+ _originalTarget = originalTarget;
+ _lastUpdated = DateTime.Now;
+ _cacheKey = args.CacheKey;
}
#region IInterceptor Members
public void Intercept(IInvocation invocation)
{
+ if (LastUpdated > _lastUpdated)
+ {
+ var newCacheKey =
+ Context.Default.ObjectCacheConfiguration.ObjectCache.GetLatestCacheKey(_cacheKey.GetId());
+ if (newCacheKey.Equals(_cacheKey))
+ {
+
+ _originalTarget = Context.Default.ObjectCacheConfiguration.ObjectCache.GetObject(newCacheKey);
+ _values = new Dictionary<string, object>();
+ _cacheKey = newCacheKey;
+ }
+ }
+
if (invocation.Method.IsSpecialName)
{
if (invocation.Method.Name.StartsWith("get_") || invocation.Method.Name.StartsWith("set_"))
View
24 Source/Glass.Mapper/Caching/Proxy/CacheProxyGenerator.cs
@@ -2,23 +2,22 @@
using System.Linq;
using Castle.DynamicProxy;
using Glass.Mapper.ObjectCaching.Proxy;
+using Glass.Mapper.Pipelines.ObjectConstruction;
using Glass.Mapper.Proxies;
namespace Glass.Mapper.Caching.Proxy
{
public class CacheProxyGenerator
{
- private static readonly ProxyGenerator _generator = new ProxyGenerator();
- private static readonly ProxyGenerationOptions _options = new ProxyGenerationOptions(new CacheProxyGeneratorHook());
+ private static readonly ProxyGenerator Generator = new ProxyGenerator();
+ private static readonly ProxyGenerationOptions Options = new ProxyGenerationOptions(new CacheProxyGeneratorHook());
- public static object CreateProxy(object originalTarget)
+ public static object CreateProxy(object originalTarget, ObjectConstructionArgs args)
{
Type type = originalTarget.GetType();
- object proxy = null ;
-
//you can't proxy a proxy.
if (originalTarget is IProxyTargetAccessor)
{
@@ -28,23 +27,14 @@ public static object CreateProxy(object originalTarget)
{
var subInterceptor = interceptors.First(x => x is InterfaceMethodInterceptor).CastTo<InterfaceMethodInterceptor>();
- return _generator.CreateInterfaceProxyWithoutTarget(
+ return Generator.CreateInterfaceProxyWithoutTarget(
type,
new CacheInterfaceMethodInterceptor(subInterceptor));
}
- else if (interceptors.Any(x => x is ProxyClassInterceptor))
- {
-
- }
-
- }
- else
- {
- proxy = _generator.CreateClassProxy(type, _options, new CacheMethodInterceptor(originalTarget));
+ return oldProxy;
}
-
- return proxy;
+ return Generator.CreateClassProxy(type, Options, new CacheMethodInterceptor(originalTarget, args));
}
}
}
View
5 Source/Glass.Mapper/Caching/Proxy/CacheProxyGeneratorHook.cs
@@ -1,10 +1,7 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using Castle.DynamicProxy;
-namespace Glass.Mapper.ObjectCaching.Proxy
+namespace Glass.Mapper.Caching.Proxy
{
public class CacheProxyGeneratorHook : IProxyGenerationHook
{
View
2 Source/Glass.Mapper/Configuration/AbstractObjectCacheConfiguration.cs
@@ -23,7 +23,7 @@ protected AbstractObjectCacheConfiguration(string contextName)
protected AbstractObjectCacheConfiguration(Context glassContext)
{
- ObjectCache = glassContext.DependencyResolver.TryResolve<IAbstractObjectCache>();
+ ObjectCache = glassContext.DependencyResolver.TryResolve<IAbstractObjectCache>();
}
}
}
View
12 Source/Glass.Mapper/Context.cs
@@ -53,6 +53,7 @@ public static Context Create(IGlassConfiguration glassConfig)
/// <summary>
/// Creates a new context and adds it to the Contexts dictionary.
/// </summary>
+ /// <param name="glassConfig"></param>
/// <param name="contextName">The context name, used as the key in the Contexts dictionary.</param>
/// <param name="isDefault">Indicates if this is the default context. If it is the context is assigned to the Default static property.</param>
/// <returns></returns>
@@ -66,13 +67,20 @@ public static Context Create(IGlassConfiguration glassConfig, string contextName
context.DependencyResolver = ResolverFactory.GetResolver();
context.DependencyResolver.Load(contextName, glassConfig);
- context.ObjectCacheConfiguration = context.DependencyResolver.TryResolve<AbstractObjectCacheConfiguration>();
-
Contexts[contextName] = context;
if (isDefault)
Default = context;
+ context.ObjectCacheConfiguration =
+ context.DependencyResolver.TryResolve<AbstractObjectCacheConfiguration>(new Dictionary<string, object>
+ {
+ {
+ "glassContext",
+ context
+ }
+ });
+
return context;
}
View
5 Source/Glass.Mapper/Glass.Mapper.csproj
@@ -79,7 +79,7 @@
<Compile Include="Caching\ObjectCaching\Exceptions\KeyNullOrEmptyObjectCacheException.cs" />
<Compile Include="Caching\ObjectCaching\ReaderWriterLock.cs" />
<Compile Include="Caching\ObjectCaching\Exceptions\ReleatedTemplateIDNullOrEmptyObjectCacheException.cs" />
- <Compile Include="Caching\Proxy\CacheInterfaceMethodInterceptor.cs" />
+ <Compile Include="Caching\Proxy\CacheLazyObjectInterceptor.cs" />
<Compile Include="Caching\Proxy\CacheMethodInterceptor.cs" />
<Compile Include="Caching\Proxy\CacheProxyGenerator.cs" />
<Compile Include="Caching\Proxy\CacheProxyGeneratorHook.cs" />
@@ -117,6 +117,7 @@
<Compile Include="IDependencyResolverFactory.cs" />
<Compile Include="IDependencyResolver.cs" />
<Compile Include="IGlassConfiguration.cs" />
+ <Compile Include="ObjectCaching\Proxy\CacheInterfaceMethodInterceptor.cs" />
<Compile Include="Profilers\IPerformanceProfiler.cs" />
<Compile Include="LazyEnumerable.cs" />
<Compile Include="MapperException.cs" />
@@ -173,4 +174,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project>
View
5 .../Proxy/CacheInterfaceMethodInterceptor.cs → .../Proxy/CacheInterfaceMethodInterceptor.cs
@@ -1,9 +1,6 @@
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Glass.Mapper.Proxies;
using Castle.DynamicProxy;
+using Glass.Mapper.Proxies;
namespace Glass.Mapper.ObjectCaching.Proxy
{
View
9 Source/Glass.Mapper/Pipelines/ObjectConstruction/ObjectConstructionArgs.cs
@@ -1,4 +1,5 @@
-using Glass.Mapper.Configuration;
+using Glass.Mapper.Caching.CacheKeyResolving;
+using Glass.Mapper.Configuration;
namespace Glass.Mapper.Pipelines.ObjectConstruction
{
@@ -14,14 +15,12 @@ public class ObjectConstructionArgs : AbstractPipelineArgs
/// </summary>
public AbstractTypeConfiguration Configuration { get; private set; }
-
-
- public bool DisableCache { get; internal set; }
-
public IAbstractService Service { get; private set; }
public virtual object Result { get; set; }
+ public ICacheKey CacheKey{ get; set; }
+
public ObjectOrigin ObjectOrigin { get; set; }
public ObjectConstructionArgs() : base()
View
3 Source/Glass.Mapper/Pipelines/ObjectConstruction/Tasks/CreateConcrete/CreateConcreteTask.cs
@@ -4,6 +4,7 @@
using System.Reflection;
using System.Text;
using Castle.DynamicProxy;
+using Glass.Mapper.Caching;
using Glass.Mapper.Profilers;
namespace Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete
@@ -48,7 +49,7 @@ public override void Execute(ObjectConstructionArgs args)
args.ObjectOrigin = ObjectOrigin.CreateConcrete;
}
- if (args.DisableCache || args.Context.ObjectCacheConfiguration == null)
+ if (CacheDisabler.CacheDisabled || args.Context.ObjectCacheConfiguration == null)
{
args.AbortPipeline();
}
View
6 ...e/Glass.Mapper/Pipelines/ObjectConstruction/Tasks/CreateConcrete/LazyObjectInterceptor.cs
@@ -1,4 +1,5 @@
using Castle.DynamicProxy;
+using Glass.Mapper.Caching;
namespace Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete
{
@@ -24,7 +25,10 @@ public void Intercept(IInvocation invocation)
if (_actual == null)
{
_args.AbstractTypeCreationContext.IsLazy = false;
- _actual = _args.Service.InstantiateObject(_args.AbstractTypeCreationContext);
+ using (new CacheDisabler())
+ {
+ _actual = _args.Service.InstantiateObject(_args.AbstractTypeCreationContext);
+ }
}
invocation.ReturnValue = invocation.Method.Invoke(_actual, invocation.Arguments);
View
7 ...ce/Glass.Mapper/Pipelines/ObjectConstruction/Tasks/CreateInterface/CreateInterfaceTask.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using Castle.DynamicProxy;
+using Glass.Mapper.Caching;
namespace Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateInterface
{
@@ -33,7 +34,11 @@ public override void Execute(ObjectConstructionArgs args)
{
args.Result = _generator.CreateInterfaceProxyWithoutTarget(args.Configuration.Type, new InterfacePropertyInterceptor(args));
args.ObjectOrigin = ObjectOrigin.CreateInterface;
- args.AbortPipeline();
+
+ if (CacheDisabler.CacheDisabled || args.Context.ObjectCacheConfiguration == null)
+ {
+ args.AbortPipeline();
+ }
}
}
}
View
5 ...per/Pipelines/ObjectConstruction/Tasks/ObjectCachingResolver/ObjectCachingResolverTask.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Glass.Mapper.Caching;
using Glass.Mapper.Caching.Proxy;
namespace Glass.Mapper.Pipelines.ObjectConstruction.Tasks.ObjectCachingResolver
@@ -10,13 +11,13 @@ public class ObjectCachingResolverTask : ObjectConstructionTask
{
public override void Execute(ObjectConstructionArgs args)
{
- if (args.DisableCache) return;
+ if (CacheDisabler.CacheDisabled) return;
if (args.Context.ObjectCacheConfiguration == null) return;
if (!args.Context.ObjectCacheConfiguration.ObjectCache.ContansObject(args)) return;
- args.Result = args.Context.ObjectCacheConfiguration.ObjectCache.GetObject(args);
+ args.Result = CacheProxyGenerator.CreateProxy(args.Context.ObjectCacheConfiguration.ObjectCache.GetObject(args), args);
args.ObjectOrigin = ObjectOrigin.ObjectCachingResolver;
args.AbortPipeline();
}
View
6 ...ss.Mapper/Pipelines/ObjectConstruction/Tasks/ObjectCachingSaver/ObjectCachingSaverTask.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Glass.Mapper.Caching;
using Glass.Mapper.Caching.Proxy;
namespace Glass.Mapper.Pipelines.ObjectConstruction.Tasks.ObjectCachingSaver
@@ -10,12 +11,11 @@ public class ObjectCachingSaverTask : ObjectConstructionTask
{
public override void Execute(ObjectConstructionArgs args)
{
- if (args.DisableCache) return;
+ if (CacheDisabler.CacheDisabled) return;
//Save item to the cache
args.Context.ObjectCacheConfiguration.ObjectCache.AddObject(args);
-
- args.Result = CacheProxyGenerator.CreateProxy(args.Result);
+ args.Result = CacheProxyGenerator.CreateProxy(args.Result, args);
}
}
}
View
76 Tests/Integration Tests/Sitecore/Glass.Mapper.Sc.Integration/SetupSitecoreForTesting.cs
@@ -17,49 +17,49 @@ namespace Glass.Mapper.Sc.Integration
[SetUpFixture]
public class SetupSitecoreForTesting
{
- [SetUp]
- public void DeployTestItems()
- {
- System.Threading.Thread.CurrentThread.ExecutionContext.GetObjectData();
- //We need to locate the TDS project that contains our test configuration. We are assuming its folder is a sibling of the project folder and we are in the /bin/[config] folder
- string currentPath = Environment.CurrentDirectory;
- string tdsProjectPath = Path.GetFullPath(Path.Combine(currentPath, "..\\..\\..\\Glass.Mapper.Sc.Integration.Tds"));
+ //[SetUp]
+ //public void DeployTestItems()
+ //{
+ // //System.Threading.Thread.CurrentThread.ExecutionContext.GetObjectData();
+ // //We need to locate the TDS project that contains our test configuration. We are assuming its folder is a sibling of the project folder and we are in the /bin/[config] folder
+ // string currentPath = Environment.CurrentDirectory;
+ // string tdsProjectPath = Path.GetFullPath(Path.Combine(currentPath, "..\\..\\..\\Glass.Mapper.Sc.Integration.Tds"));
- string msBuildPath = ConfigurationManager.AppSettings["MSBuildPath"];
+ // string msBuildPath = ConfigurationManager.AppSettings["MSBuildPath"];
- ProcessStartInfo psi = new ProcessStartInfo
- {
- UseShellExecute = false,
- FileName = Path.Combine(msBuildPath, "MSBuild.exe"),
- Arguments = "/t:Deploy Glass.Mapper.Sc.Integration.Tds.scproj",
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- WorkingDirectory = tdsProjectPath
- };
+ // ProcessStartInfo psi = new ProcessStartInfo
+ // {
+ // UseShellExecute = false,
+ // FileName = Path.Combine(msBuildPath, "MSBuild.exe"),
+ // Arguments = "/t:Deploy Glass.Mapper.Sc.Integration.Tds.scproj",
+ // RedirectStandardOutput = true,
+ // RedirectStandardError = true,
+ // WorkingDirectory = tdsProjectPath
+ // };
- //Start the TDS deploy
- using (Process buildProc = Process.Start(psi))
- {
- //Show the output in the console for debugging purposes
- while (!buildProc.HasExited)
- {
- string output = buildProc.StandardOutput.ReadLine();
- Debug.WriteLine(output);
- Console.WriteLine(output);
- }
+ // //Start the TDS deploy
+ // using (Process buildProc = Process.Start(psi))
+ // {
+ // //Show the output in the console for debugging purposes
+ // while (!buildProc.HasExited)
+ // {
+ // string output = buildProc.StandardOutput.ReadLine();
+ // Debug.WriteLine(output);
+ // Console.WriteLine(output);
+ // }
- //If there are any failues, show the standard error contents
- if (buildProc.ExitCode != 0)
- {
- Console.WriteLine("\n\nStandard Error:");
+ // //If there are any failues, show the standard error contents
+ // if (buildProc.ExitCode != 0)
+ // {
+ // Console.WriteLine("\n\nStandard Error:");
- while (!buildProc.StandardError.EndOfStream)
- {
- Console.WriteLine(buildProc.StandardError.ReadLine());
- }
- }
- }
- }
+ // while (!buildProc.StandardError.EndOfStream)
+ // {
+ // Console.WriteLine(buildProc.StandardError.ReadLine());
+ // }
+ // }
+ // }
+ //}
}
}
#endif
View
93 Tests/Unit Tests/Glass.Mapper.Tests/Caching/CacheInformationFixture.cs
@@ -4,7 +4,9 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Glass.Mapper.Caching.CacheKeyResolving;
using Glass.Mapper.Caching.ObjectCaching;
+using NSubstitute;
using NUnit.Framework;
namespace Glass.Mapper.Tests.Caching
@@ -15,15 +17,15 @@ public class CacheInformationFixture
[Test]
public void Can_Create_CreateCacheInformation()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
Assert.IsNotNull(ci);
}
[Test]
public void Can_Add_Related_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Related_Key";
ci.AddRelatedKey(releatedKey);
@@ -34,7 +36,7 @@ public void Can_Add_Related_Key()
[Test]
public void Can_Add_Related_Key_Thread_Safe()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Related_Key";
@@ -53,7 +55,7 @@ public void Can_Add_Related_Key_Thread_Safe()
[Test]
public void Can_Add_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Key_Related_Key";
var key = "Can_Add_Key";
ci.AddObjectKey(releatedKey, key);
@@ -64,7 +66,7 @@ public void Can_Add_Key()
[Test]
public void Can_Add_Key_Thread_Safe()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Key_Related_Key";
var key = "Can_Add_Key";
@@ -84,7 +86,7 @@ public void Can_Add_Key_Thread_Safe()
[Test]
public void Does_CacheInformation_Contain_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Key_Related_Key";
var key = "Can_Add_Key";
ci.AddObjectKey(releatedKey, key);
@@ -97,7 +99,7 @@ public void Does_CacheInformation_Contain_Key()
[Test]
public void Does_CacheInformation_Contain_Related_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Key_Related_Key";
var key = "Can_Add_Key";
ci.AddObjectKey(releatedKey, key);
@@ -111,7 +113,7 @@ public void Does_CacheInformation_Contain_Related_Key()
[Test]
public void Does_CacheInformation_Contain_Key_Thread_Safe()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Key_Related_Key";
var key = "Can_Add_Key";
ci.AddObjectKey(releatedKey, key);
@@ -135,11 +137,11 @@ public void Does_CacheInformation_Contain_Key_Thread_Safe()
[Test]
public void Test_LookUp_Time_For_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Key_Related_Key";
var key = "Can_Add_Key";
- Parallel.For(0, 100000, i =>
+ Parallel.For(0, 1000, i =>
{
ci.AddObjectKey(releatedKey + i, key + i);
});
@@ -156,7 +158,7 @@ public void Test_LookUp_Time_For_Key()
[Test]
public void Can_Get_Add_List_Of_Related_Keys_With_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var relatedKey1 = "Related_Key1";
var relatedKey2 = "Related_Key2";
@@ -172,7 +174,7 @@ public void Can_Get_Add_List_Of_Related_Keys_With_Key()
[Test]
public void Can_Get_List_Of_Related_Keys_From_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Add_Key_Related_Key";
var key1 = "key1";
@@ -190,7 +192,7 @@ public void Can_Get_List_Of_Related_Keys_From_Key()
[Test]
public void Can_Remove_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Remove_Key_Related_Key";
var key = "Can_Remove_Key";
ci.AddObjectKey(releatedKey, key);
@@ -206,7 +208,7 @@ public void Can_Remove_Key()
[Test]
public void Can_Remove_Key_By_Related_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Remove_Key_Related_Key";
var key = "Can_Remove_Key";
ci.AddObjectKey(releatedKey, key);
@@ -221,7 +223,7 @@ public void Can_Remove_Key_By_Related_Key()
[Test]
public void Related_Key_Is_Removed_When_Remove_Key_By_Related_Key()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Remove_Key_Related_Key";
var key = "Can_Remove_Key";
ci.AddObjectKey(releatedKey, key);
@@ -236,7 +238,7 @@ public void Related_Key_Is_Removed_When_Remove_Key_By_Related_Key()
[Test]
public void Related_Key_Is_Removed_When_No_Keys_Are_Left()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Remove_Key_Related_Key";
var key = "Can_Remove_Key";
ci.AddObjectKey(releatedKey, key);
@@ -252,7 +254,7 @@ public void Related_Key_Is_Removed_When_No_Keys_Are_Left()
[Test]
public void Related_Key_Is_Removed_When_No_Keys_Are_Left_Thread_Safe()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var releatedKey = "Can_Remove_Key_Related_Key";
var key = "Can_Remove_Key";
@@ -275,7 +277,7 @@ public void Related_Key_Is_Removed_When_No_Keys_Are_Left_Thread_Safe()
[Test]
public void List_Related_Key_Is_Removed_When_No_Keys_Are_Left()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var relatedKey1 = "Related_Key1";
var relatedKey2 = "Related_Key2";
@@ -297,7 +299,7 @@ public void List_Related_Key_Is_Removed_When_No_Keys_Are_Left()
[Test]
public void List_Related_Key_Is_Removed_When_No_Keys_Are_Left_Thread_Safe()
{
- var ci = new CacheInformation();
+ var ci = new CacheInformation<int>();
var relatedKey1 = "Related_Key1";
var relatedKey2 = "Related_Key2";
@@ -317,10 +319,63 @@ public void List_Related_Key_Is_Removed_When_No_Keys_Are_Left_Thread_Safe()
Assert.IsFalse(((List<string>)ci.GetRelatedKeys()).Any(x => x == relatedKey1 + i));
Assert.IsFalse(((List<string>)ci.GetRelatedKeys()).Any(x => x == relatedKey2 + i));
});
+ }
+
+ [Test]
+ public void Can_Add_CacheKey()
+ {
+ var ci = new CacheInformation<int>();
+ var id = 1;
+ var ck = Substitute.For<CacheKey<int>>(id, 1, "", typeof(StubClass));
+ ci.AddCacheKey(id, ck);
+
+ Assert.IsTrue(ci.ContainsCacheKey(id, ck));
+ }
+
+ [Test]
+ public void Can_Add_CacheKey_Thread_Safe()
+ {
+ var ci = new CacheInformation<int>();
+ Parallel.For(0, 10000, i =>
+ {
+ var id = i;
+ var ck = Substitute.For<CacheKey<int>>(id, i, "", typeof (StubClass));
+ ci.AddCacheKey(id, ck);
+
+ Assert.IsTrue(ci.ContainsCacheKey(id, ck));
+ });
+ }
+
+
+ [Test]
+ public void Can_Get_CacheKey()
+ {
+ var ci = new CacheInformation<int>();
+ var id = 1;
+ var ck = Substitute.For<CacheKey<int>>(id, 1, "", typeof(StubClass));
+ ci.AddCacheKey(id, ck);
+
+ Assert.IsTrue(ci.ContainsCacheKey(id, ck));
+ Assert.AreEqual(ck, ci.GetCacheKeys(id).First());
+ }
+ #region Stubs
+
+ public class StubClass
+ {
+
+ public string MyProperty { get; set; }
}
+ public interface IStubInterface
+ {
+
+ }
+
+
+
+ #endregion
}
}
View
50 Tests/Unit Tests/Glass.Mapper.Tests/Caching/ProxiesFixture.cs
@@ -0,0 +1,50 @@
+using Glass.Mapper.Caching.CacheKeyResolving;
+using Glass.Mapper.Caching.Proxy;
+using Glass.Mapper.Pipelines.ObjectConstruction;
+using NSubstitute;
+using NUnit.Framework;
+
+namespace Glass.Mapper.Tests.Caching
+{
+ [TestFixture]
+ public class ProxiesFixture
+ {
+ private CacheKey<int> _cacheKey;
+ private ObjectConstructionArgs _args;
+ private AbstractCacheKeyResolver<int> _cacheKeyResolver;
+
+ [SetUp]
+ public void SetUp()
+ {
+ _cacheKey = Substitute.For<CacheKey<int>>();
+ _args = Substitute.For<ObjectConstructionArgs>();
+ _cacheKeyResolver = Substitute.For<AbstractCacheKeyResolver<int>>();
+ _cacheKeyResolver.GetKey(_args).Returns(_cacheKey);
+ }
+
+ [Test]
+ public void Can_Create_Proxy_For_Object()
+ {
+ var test = new StubClass();
+ CacheProxyGenerator.CreateProxy(test, _args);
+ }
+
+ #region Stubs
+
+ public class StubClass
+ {
+
+ public string MyProperty { get; set; }
+ }
+
+ public interface IStubInterface
+ {
+
+ }
+
+
+
+
+ #endregion
+ }
+}
View
1 Tests/Unit Tests/Glass.Mapper.Tests/Glass.Mapper.Tests.csproj
@@ -70,6 +70,7 @@
<Compile Include="Caching\CacheInformationFixture.cs" />
<Compile Include="Caching\CacheTableFixture.cs" />
<Compile Include="Caching\AbstractObjectCacheFixture.cs" />
+ <Compile Include="Caching\ProxiesFixture.cs" />
<Compile Include="Configuration\AbstractTypeConfigurationFixture.cs" />
<Compile Include="Configuration\Attributes\AttributeConfigurationLoaderFixture.cs" />
<Compile Include="Configuration\Attributes\AbstractClassAttributeFixture.cs" />

0 comments on commit cd0d841

Please sign in to comment.
Something went wrong with that request. Please try again.