|
From: <jer...@us...> - 2008-12-20 17:59:49
|
Revision: 204
http://structuremap.svn.sourceforge.net/structuremap/?rev=204&view=rev
Author: jeremydmiller
Date: 2008-12-20 17:59:45 +0000 (Sat, 20 Dec 2008)
Log Message:
-----------
Refactored the BuildPolicy caching strategies to use the Cache object and make it easier to add new types of CacheInterceptor
Modified Paths:
--------------
trunk/Source/CommonAssemblyInfo.cs
trunk/Source/StructureMap/BuildSession.cs
trunk/Source/StructureMap/Emitting/Parameters/Methods.cs
trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs
trunk/Source/StructureMap/Graph/PluginCache.cs
trunk/Source/StructureMap/Graph/PluginFamily.cs
trunk/Source/StructureMap/Graph/SetterProperty.cs
trunk/Source/StructureMap/InstanceFactory.cs
trunk/Source/StructureMap/Pipeline/CacheInterceptor.cs
trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs
trunk/Source/StructureMap/Pipeline/SingletonPolicy.cs
trunk/Source/StructureMap/Pipeline/ThreadLocalStoragePolicy.cs
trunk/Source/StructureMap/StructureMap.csproj
trunk/Source/StructureMap/Util/Cache.cs
trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
Added Paths:
-----------
trunk/Source/StructureMap/Pipeline/HttpContextBuildStorage.cs
trunk/Source/StructureMap/Pipeline/InstanceKey.cs
trunk/Source/StructureMap.Testing/Bugs/
trunk/Source/StructureMap.Testing/Bugs/ScanIndexerBugTester.cs
Removed Paths:
-------------
trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs
Modified: trunk/Source/CommonAssemblyInfo.cs
===================================================================
--- trunk/Source/CommonAssemblyInfo.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/CommonAssemblyInfo.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -14,9 +14,10 @@
[assembly: ComVisibleAttribute(false)]
[assembly: AssemblyVersionAttribute("2.5.0.0000")]
-[assembly: AssemblyCopyrightAttribute("Copyright (c) 2007, Jeremy D. Miller")]
+[assembly: AssemblyCopyrightAttribute("Copyright (c) 2003-2008, Jeremy D. Miller")]
[assembly: AssemblyProductAttribute("StructureMap")]
[assembly: AssemblyCompanyAttribute("")]
[assembly: AssemblyConfigurationAttribute("release")]
[assembly: AssemblyInformationalVersionAttribute("2.5.0.0000")]
+[assembly: AssemblyFileVersionAttribute("2.5.0.0000")]
Modified: trunk/Source/StructureMap/BuildSession.cs
===================================================================
--- trunk/Source/StructureMap/BuildSession.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/BuildSession.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -142,7 +142,7 @@
public virtual object CreateInstance(Type pluginType)
{
- return _defaults.Retrieve(pluginType);
+ return _defaults[pluginType];
}
public virtual object ApplyInterception(Type pluginType, object actualValue)
@@ -153,7 +153,7 @@
public virtual void RegisterDefault(Type pluginType, object defaultObject)
{
- _defaults.Store(pluginType, defaultObject);
+ _defaults[pluginType] = defaultObject;
}
Modified: trunk/Source/StructureMap/Emitting/Parameters/Methods.cs
===================================================================
--- trunk/Source/StructureMap/Emitting/Parameters/Methods.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Emitting/Parameters/Methods.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -39,7 +39,7 @@
public static MethodInfo ParseFor(Type type)
{
- return _parseMethods.Retrieve(type);
+ return _parseMethods[type];
}
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs
===================================================================
--- trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Graph/GenericsPluginGraph.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -81,7 +81,7 @@
public void AddFamily(PluginFamily family)
{
- _families.Store(family.PluginType, family);
+ _families[family.PluginType] = family;
}
@@ -91,7 +91,7 @@
if (_families.Has(basicType))
{
- PluginFamily basicFamily = _families.Retrieve(basicType);
+ PluginFamily basicFamily = _families[basicType];
Type[] templatedParameterTypes = templatedType.GetGenericArguments();
@@ -158,7 +158,7 @@
public PluginFamily FindFamily(Type pluginType)
{
- return _families.Retrieve(pluginType);
+ return _families[pluginType];
}
public bool HasFamily(Type pluginType)
Modified: trunk/Source/StructureMap/Graph/PluginCache.cs
===================================================================
--- trunk/Source/StructureMap/Graph/PluginCache.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Graph/PluginCache.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -17,7 +17,7 @@
_plugins = new Cache<Type, Plugin>(t => new Plugin(t));
_builders = new Cache<Type, InstanceBuilder>(t =>
{
- Plugin plugin = _plugins.Retrieve(t);
+ Plugin plugin = _plugins[t];
plugin.SetFilledTypes(_filledTypes);
return new InstanceBuilderAssembly(new[] {plugin}).Compile()[0];
});
@@ -25,12 +25,12 @@
public static Plugin GetPlugin(Type pluggedType)
{
- return _plugins.Retrieve(pluggedType);
+ return _plugins[pluggedType];
}
public static InstanceBuilder FindBuilder(Type pluggedType)
{
- return _builders.Retrieve(pluggedType);
+ return _builders[pluggedType];
}
public static void Compile()
@@ -51,7 +51,7 @@
}
var assembly = new InstanceBuilderAssembly(plugins);
- assembly.Compile().ForEach(b => _builders.Store(b.PluggedType, b));
+ assembly.Compile().ForEach(b => _builders[b.PluggedType] = b);
}
private static bool pluginHasNoBuilder(Plugin plugin)
@@ -61,7 +61,7 @@
public static void Store(Type pluggedType, InstanceBuilder builder)
{
- _builders.Store(pluggedType, builder);
+ _builders[pluggedType] = builder;
}
internal static void ResetAll()
Modified: trunk/Source/StructureMap/Graph/PluginFamily.cs
===================================================================
--- trunk/Source/StructureMap/Graph/PluginFamily.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Graph/PluginFamily.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -95,7 +95,7 @@
public void AddInstance(Instance instance)
{
- _instances.Store(instance.Name, instance);
+ _instances[instance.Name] = instance;
}
@@ -170,7 +170,7 @@
public Instance GetInstance(string name)
{
- return _instances.Retrieve(name);
+ return _instances[name];
}
public bool HasPlugin(Type pluggedType)
@@ -196,7 +196,7 @@
assertPluggability(pluggedType);
Plugin plugin = PluginCache.GetPlugin(pluggedType);
- _pluggedTypes.Store(plugin.ConcreteKey, plugin);
+ _pluggedTypes[plugin.ConcreteKey] = plugin;
return plugin;
}
@@ -206,7 +206,7 @@
assertPluggability(pluggedType);
Plugin plugin = PluginCache.GetPlugin(pluggedType);
- _pluggedTypes.Store(key, plugin);
+ _pluggedTypes[key] = plugin;
return plugin;
}
@@ -263,7 +263,7 @@
{
if (_pluggedTypes.Has(concreteKey))
{
- return _pluggedTypes.Retrieve(concreteKey);
+ return _pluggedTypes[concreteKey];
}
return null;
Modified: trunk/Source/StructureMap/Graph/SetterProperty.cs
===================================================================
--- trunk/Source/StructureMap/Graph/SetterProperty.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Graph/SetterProperty.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -41,6 +41,9 @@
{
Type propertyType = _property.PropertyType;
+ // Ignore indexer properties
+ if (_property.GetIndexParameters().Length > 0) return;
+
if (IsPrimitive(propertyType)) visitor.PrimitiveSetter(_property, IsMandatory);
if (IsChild(propertyType)) visitor.ChildSetter(_property, IsMandatory);
if (IsChildArray(propertyType)) visitor.ChildArraySetter(_property, IsMandatory);
Modified: trunk/Source/StructureMap/InstanceFactory.cs
===================================================================
--- trunk/Source/StructureMap/InstanceFactory.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/InstanceFactory.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -96,7 +96,7 @@
public void AddInstance(Instance instance)
{
- _instances.Store(instance.Name, instance);
+ _instances[instance.Name] = instance;
}
@@ -131,7 +131,7 @@
public Instance FindInstance(string name)
{
- return _instances.Retrieve(name);
+ return _instances[name];
}
public void ImportFrom(PluginFamily family)
Modified: trunk/Source/StructureMap/Pipeline/CacheInterceptor.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/CacheInterceptor.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Pipeline/CacheInterceptor.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -1,7 +1,15 @@
using System;
+using StructureMap.Util;
namespace StructureMap.Pipeline
{
+ public class InstanceCache : Cache<InstanceKey, object>
+ {
+ public InstanceCache(IBuildPolicy innerPolicy) : base(key => innerPolicy.Build(key.Session, key.PluginType, key.Instance))
+ {
+ }
+ }
+
public abstract class CacheInterceptor : IBuildInterceptor
{
private readonly object _locker = new object();
@@ -15,22 +23,17 @@
set { _innerPolicy = value; }
}
+ protected InstanceCache buildNewCache()
+ {
+ return new InstanceCache(_innerPolicy);
+ }
+ protected abstract InstanceCache findCache();
+
public object Build(BuildSession buildSession, Type pluginType, Instance instance)
{
- if (!isCached(instance.Name, pluginType))
- {
- lock (_locker)
- {
- if (!isCached(instance.Name, pluginType))
- {
- object returnValue = _innerPolicy.Build(buildSession, pluginType, instance);
- storeInCache(instance.Name, pluginType, returnValue);
- }
- }
- }
-
- return retrieveFromCache(instance.Name, pluginType);
+ var key = new InstanceKey{Instance = instance, PluginType = pluginType, Session = buildSession};
+ return findCache()[key];
}
public IBuildPolicy Clone()
@@ -45,10 +48,6 @@
protected abstract CacheInterceptor clone();
- protected abstract void storeInCache(string instanceKey, Type pluginType, object instance);
- protected abstract bool isCached(string instanceKey, Type pluginType);
- protected abstract object retrieveFromCache(string instanceKey, Type pluginType);
-
public override string ToString()
{
return GetType().FullName + " / " + _innerPolicy;
Deleted: trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Pipeline/HttpContextBuildPolicy.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -1,41 +0,0 @@
-using System;
-using System.Web;
-
-namespace StructureMap.Pipeline
-{
- public class HttpContextBuildPolicy : CacheInterceptor
- {
- private string _prefix = Guid.NewGuid().ToString();
-
-
- public static bool HasContext()
- {
- return HttpContext.Current != null;
- }
-
- protected override void storeInCache(string instanceKey, Type pluginType, object instance)
- {
- HttpContext.Current.Items.Add(getKey(instanceKey, pluginType), instance);
- }
-
- protected override bool isCached(string instanceKey, Type pluginType)
- {
- return HttpContext.Current.Items.Contains(getKey(instanceKey, pluginType));
- }
-
- protected override object retrieveFromCache(string instanceKey, Type pluginType)
- {
- return HttpContext.Current.Items[getKey(instanceKey, pluginType)];
- }
-
- private string getKey(string instanceKey, Type pluginType)
- {
- return string.Format("{0}:{1}:{2}", pluginType.AssemblyQualifiedName, instanceKey, _prefix);
- }
-
- protected override CacheInterceptor clone()
- {
- return this;
- }
- }
-}
\ No newline at end of file
Added: trunk/Source/StructureMap/Pipeline/HttpContextBuildStorage.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/HttpContextBuildStorage.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/HttpContextBuildStorage.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -0,0 +1,41 @@
+using System.Collections;
+using System.Web;
+
+namespace StructureMap.Pipeline
+{
+ public class HttpContextBuildPolicy : CacheInterceptor
+ {
+ public static readonly string ITEM_NAME = "STRUCTUREMAP-INSTANCES";
+
+ public static bool HasContext()
+ {
+ return HttpContext.Current != null;
+ }
+
+ protected override InstanceCache findCache()
+ {
+ IDictionary items = HttpContext.Current.Items;
+
+ if (!items.Contains(ITEM_NAME))
+ {
+ lock (items.SyncRoot)
+ {
+ if (!items.Contains(ITEM_NAME))
+ {
+ InstanceCache cache = buildNewCache();
+ items.Add(ITEM_NAME, cache);
+
+ return cache;
+ }
+ }
+ }
+
+ return (InstanceCache) items[ITEM_NAME];
+ }
+
+ protected override CacheInterceptor clone()
+ {
+ return this;
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Pipeline/HybridBuildPolicy.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -2,15 +2,17 @@
namespace StructureMap.Pipeline
{
- public class HybridBuildPolicy : IBuildInterceptor
+ public abstract class HttpBuildPolicyBase<HTTP, NONHTTP> : IBuildInterceptor
+ where HTTP : IBuildInterceptor, new()
+ where NONHTTP : IBuildInterceptor, new()
{
private readonly IBuildInterceptor _http;
- private readonly IBuildInterceptor _threadLocal;
+ private readonly IBuildInterceptor _nonHttp;
- public HybridBuildPolicy()
+ public HttpBuildPolicyBase()
{
- _http = new HttpContextBuildPolicy();
- _threadLocal = new ThreadLocalStoragePolicy();
+ _http = new HTTP();
+ _nonHttp = new NONHTTP();
}
private IBuildPolicy _innerPolicy;
@@ -22,19 +24,17 @@
{
return HttpContextBuildPolicy.HasContext()
? _http
- : _threadLocal;
+ : _nonHttp;
}
}
- #region IBuildInterceptor Members
-
public IBuildPolicy InnerPolicy
{
get { return _innerPolicy; }
set
{
_http.InnerPolicy = value;
- _threadLocal.InnerPolicy = value;
+ _nonHttp.InnerPolicy = value;
_innerPolicy = value;
}
}
@@ -44,14 +44,16 @@
return interceptor.Build(buildSession, pluginType, instance);
}
- public IBuildPolicy Clone()
+ public abstract IBuildPolicy Clone();
+ }
+
+
+ public class HybridBuildPolicy : HttpBuildPolicyBase<HttpContextBuildPolicy, ThreadLocalStoragePolicy>
+ {
+ public override IBuildPolicy Clone()
{
- var policy = new HybridBuildPolicy();
- policy.InnerPolicy = _innerPolicy.Clone();
-
- return policy;
+ return new HybridBuildPolicy(){InnerPolicy = InnerPolicy.Clone()};
}
+ }
- #endregion
- }
}
\ No newline at end of file
Added: trunk/Source/StructureMap/Pipeline/InstanceKey.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/InstanceKey.cs (rev 0)
+++ trunk/Source/StructureMap/Pipeline/InstanceKey.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -0,0 +1,60 @@
+using System;
+
+namespace StructureMap.Pipeline
+{
+ public class InstanceKey
+ {
+ public string Name { get; set; }
+ public Type PluginType { get; set; }
+ private WeakReference _session;
+ private WeakReference _instance;
+
+ public InstanceKey()
+ {
+ }
+
+
+
+ public BuildSession Session
+ {
+ get { return (BuildSession) _session.Target; }
+ set { _session = new WeakReference(value); }
+ }
+
+ public Instance Instance
+ {
+ get
+ {
+ return (Instance) _instance.Target;
+ }
+ set
+ {
+ Name = value.Name;
+ _instance = new WeakReference(value);
+ }
+ }
+
+ public bool Equals(InstanceKey obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ return Equals(obj.Name, Name) && Equals(obj.PluginType, PluginType);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != typeof(InstanceKey)) return false;
+ return Equals((InstanceKey)obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ (PluginType != null ? PluginType.GetHashCode() : 0);
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Pipeline/SingletonPolicy.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/SingletonPolicy.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Pipeline/SingletonPolicy.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -1,28 +1,27 @@
-using System;
-using System.Collections.Generic;
-
namespace StructureMap.Pipeline
{
[Pluggable("Singleton")]
public class SingletonPolicy : CacheInterceptor
{
- private readonly Dictionary<string, object> _instances = new Dictionary<string, object>();
+ private readonly object _locker = new object();
+ private InstanceCache _cache;
- protected override void storeInCache(string instanceKey, Type pluginType, object instance)
+ protected override InstanceCache findCache()
{
- _instances.Add(instanceKey, instance);
- }
+ if (_cache == null)
+ {
+ lock (_locker)
+ {
+ if (_cache == null)
+ {
+ _cache = buildNewCache();
+ }
+ }
+ }
- protected override bool isCached(string instanceKey, Type pluginType)
- {
- return _instances.ContainsKey(instanceKey);
+ return _cache;
}
- protected override object retrieveFromCache(string instanceKey, Type pluginType)
- {
- return _instances[instanceKey];
- }
-
protected override CacheInterceptor clone()
{
return new SingletonPolicy();
Modified: trunk/Source/StructureMap/Pipeline/ThreadLocalStoragePolicy.cs
===================================================================
--- trunk/Source/StructureMap/Pipeline/ThreadLocalStoragePolicy.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Pipeline/ThreadLocalStoragePolicy.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -1,48 +1,32 @@
using System;
-using System.Collections.Generic;
namespace StructureMap.Pipeline
{
public class ThreadLocalStoragePolicy : CacheInterceptor
{
- [ThreadStatic] private static Dictionary<string, object> _instances;
+ [ThreadStatic] private static InstanceCache _cache;
private readonly object _locker = new object();
private void guaranteeHashExists()
{
- if (_instances == null)
+ if (_cache == null)
{
lock (_locker)
{
- if (_instances == null)
+ if (_cache == null)
{
- _instances = new Dictionary<string, object>();
+ _cache = buildNewCache();
}
}
}
}
- protected override void storeInCache(string instanceKey, Type pluginType, object instance)
+ protected override InstanceCache findCache()
{
- _instances.Add(getKey(instanceKey, pluginType), instance);
- }
-
- protected override bool isCached(string instanceKey, Type pluginType)
- {
guaranteeHashExists();
- return _instances.ContainsKey(getKey(instanceKey, pluginType));
+ return _cache;
}
- protected override object retrieveFromCache(string instanceKey, Type pluginType)
- {
- return _instances[getKey(instanceKey, pluginType)];
- }
-
- private string getKey(string instanceKey, Type pluginType)
- {
- return string.Format("{0}:{1}", pluginType.AssemblyQualifiedName, instanceKey);
- }
-
protected override CacheInterceptor clone()
{
return this;
Modified: trunk/Source/StructureMap/StructureMap.csproj
===================================================================
--- trunk/Source/StructureMap/StructureMap.csproj 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/StructureMap.csproj 2008-12-20 17:59:45 UTC (rev 204)
@@ -167,7 +167,6 @@
<Compile Include="Pipeline\ConfiguredInstance.Expressions.cs" />
<Compile Include="Pipeline\ConstructorInstance.cs" />
<Compile Include="Pipeline\DefaultInstance.cs" />
- <Compile Include="Pipeline\HttpContextBuildPolicy.cs" />
<Compile Include="Pipeline\HybridBuildPolicy.cs" />
<Compile Include="Pipeline\IBuildInterceptor.cs" />
<Compile Include="Pipeline\IBuildPolicy.cs" />
@@ -412,6 +411,8 @@
<Compile Include="Pipeline\BuildFrame.cs" />
<Compile Include="Pipeline\BuildStack.cs" />
<Compile Include="Pipeline\ConfiguredInstanceBase.cs" />
+ <Compile Include="Pipeline\HttpContextBuildStorage.cs" />
+ <Compile Include="Pipeline\InstanceKey.cs" />
<Compile Include="Pipeline\IStructuredInstance.cs" />
<Compile Include="Pipeline\PropertyExpression.cs" />
<Compile Include="Pipeline\SerializedInstance.cs" />
Modified: trunk/Source/StructureMap/Util/Cache.cs
===================================================================
--- trunk/Source/StructureMap/Util/Cache.cs 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap/Util/Cache.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -6,26 +6,43 @@
{
public class Cache<KEY, VALUE> : IEnumerable<VALUE> where VALUE : class
{
- private readonly Func<KEY, VALUE> _onMissing = key =>
+ private readonly object _locker = new object();
+ private readonly IDictionary<KEY, VALUE> _values;
+
+ private Func<VALUE, KEY> _getKey = delegate { throw new NotImplementedException(); };
+
+ private Func<KEY, VALUE> _onMissing = delegate(KEY key)
{
string message = string.Format("Key '{0}' could not be found", key);
throw new KeyNotFoundException(message);
};
- private readonly Dictionary<KEY, VALUE> _values = new Dictionary<KEY, VALUE>();
-
- private Func<VALUE, KEY> _getKey = delegate { throw new NotImplementedException(); };
- private readonly object _valuesLock = new object();
-
public Cache()
+ : this(new Dictionary<KEY, VALUE>())
{
}
public Cache(Func<KEY, VALUE> onMissing)
+ : this(new Dictionary<KEY, VALUE>(), onMissing)
{
+ }
+
+ public Cache(IDictionary<KEY, VALUE> dictionary, Func<KEY, VALUE> onMissing)
+ : this(dictionary)
+ {
_onMissing = onMissing;
}
+ public Cache(IDictionary<KEY, VALUE> dictionary)
+ {
+ _values = dictionary;
+ }
+
+ public Func<KEY, VALUE> OnMissing
+ {
+ set { _onMissing = value; }
+ }
+
public Func<VALUE, KEY> GetKey
{
get { return _getKey; }
@@ -50,11 +67,43 @@
}
}
+
+ public VALUE this[KEY key]
+ {
+ get
+ {
+ if (!_values.ContainsKey(key))
+ {
+ lock (_locker)
+ {
+ if (!_values.ContainsKey(key))
+ {
+ VALUE value = _onMissing(key);
+ _values.Add(key, value);
+ }
+ }
+ }
+
+ return _values[key];
+ }
+ set
+ {
+ if (_values.ContainsKey(key))
+ {
+ _values[key] = value;
+ }
+ else
+ {
+ _values.Add(key, value);
+ }
+ }
+ }
+
#region IEnumerable<VALUE> Members
IEnumerator IEnumerable.GetEnumerator()
{
- return ((IEnumerable<VALUE>) this).GetEnumerator();
+ return ((IEnumerable<VALUE>)this).GetEnumerator();
}
public IEnumerator<VALUE> GetEnumerator()
@@ -64,16 +113,6 @@
#endregion
- public void Clear()
- {
- _values.Clear();
- }
-
- public void Store(KEY key, VALUE value)
- {
- _values[key] = value;
- }
-
public void Fill(KEY key, VALUE value)
{
if (_values.ContainsKey(key))
@@ -84,22 +123,17 @@
_values.Add(key, value);
}
- public VALUE Retrieve(KEY key)
+ public bool TryRetrieve(KEY key, out VALUE value)
{
- if (!_values.ContainsKey(key))
+ value = default(VALUE);
+
+ if (_values.ContainsKey(key))
{
- lock (_valuesLock)
- {
- if (!_values.ContainsKey(key))
- {
- // Potential deadlock if _onMissing attempts to retrieve the same key
- VALUE value = _onMissing(key);
- _values.Add(key, value);
- }
- }
+ value = _values[key];
+ return true;
}
- return _values[key];
+ return false;
}
public void Each(Action<VALUE> action)
@@ -127,7 +161,7 @@
{
bool returnValue = false;
- Each(value => returnValue |= predicate(value));
+ Each(delegate(VALUE value) { returnValue |= predicate(value); });
return returnValue;
}
@@ -155,7 +189,15 @@
public void Remove(KEY key)
{
- _values.Remove(key);
+ if (_values.ContainsKey(key))
+ {
+ _values.Remove(key);
+ }
}
+
+ public void Clear()
+ {
+ _values.Clear();
+ }
}
}
\ No newline at end of file
Added: trunk/Source/StructureMap.Testing/Bugs/ScanIndexerBugTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Bugs/ScanIndexerBugTester.cs (rev 0)
+++ trunk/Source/StructureMap.Testing/Bugs/ScanIndexerBugTester.cs 2008-12-20 17:59:45 UTC (rev 204)
@@ -0,0 +1,31 @@
+using NUnit.Framework;
+
+namespace StructureMap.Testing.Bugs
+{
+ [TestFixture]
+ public class ScanIndexerBugTester
+ {
+ [Test]
+ public void do_not_blow_up_on_scanning_the_property_for_indexer()
+ {
+ var container = new Container();
+ container.GetInstance<ClassWithIndexer>().ShouldNotBeNull();
+ }
+ }
+
+ public class ClassWithIndexer
+ {
+
+ public string this[string key]
+ {
+ get
+ {
+ return key;
+ }
+ set
+ {
+
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj
===================================================================
--- trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-12-19 19:04:47 UTC (rev 203)
+++ trunk/Source/StructureMap.Testing/StructureMap.Testing.csproj 2008-12-20 17:59:45 UTC (rev 204)
@@ -1,7 +1,7 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
- <ProductVersion>9.0.30729</ProductVersion>
+ <ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{63C2742D-B6E2-484F-AFDB-346873075C5E}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -178,6 +178,7 @@
<Compile Include="AutoMocking\MoqFactoryTester.cs" />
<Compile Include="AutoMocking\RhinoAutoMockerTester.cs" />
<Compile Include="AutoMocking\RhinoMockRepositoryProxyTester.cs" />
+ <Compile Include="Bugs\ScanIndexerBugTester.cs" />
<Compile Include="BuildSessionTester.cs" />
<Compile Include="Configuration\ConfigurationParserBuilderTester.cs" />
<Compile Include="Configuration\ConfigurationParserTester.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|