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. |