From: <jer...@us...> - 2010-02-04 03:17:14
|
Revision: 336 http://structuremap.svn.sourceforge.net/structuremap/?rev=336&view=rev Author: jeremydmiller Date: 2010-02-04 03:17:07 +0000 (Thu, 04 Feb 2010) Log Message: ----------- Made disposing a container much, much more robust Modified Paths: -------------- trunk/Source/StructureMap/Container.cs trunk/Source/StructureMap/InstanceFactory.cs trunk/Source/StructureMap/Pipeline/MainObjectCache.cs trunk/Source/StructureMap/Pipeline/ObjectInstance.cs trunk/Source/StructureMap/PipelineGraph.cs trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs trunk/Source/StructureMap/TypeExtensions.cs trunk/Source/StructureMap.Testing/Pipeline/ContainerDisposalTester.cs Modified: trunk/Source/StructureMap/Container.cs =================================================================== --- trunk/Source/StructureMap/Container.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap/Container.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -442,6 +442,7 @@ { _interceptorLibrary = _interceptorLibrary, _pipelineGraph = _pipelineGraph.ToNestedGraph(), + _onDispose = nestedDispose }; // Fixes a mild bug. The child container should inject itself @@ -463,11 +464,25 @@ return container; } + + private Action<Container> _onDispose = fullDispose; public void Dispose() { - _pipelineGraph.Dispose(); + _onDispose(this); } + private static void fullDispose(Container c) + { + c.Model.AllInstances.Each(i => i.EjectObject()); + + nestedDispose(c); + } + + private static void nestedDispose(Container c) + { + c._pipelineGraph.Dispose(); + } + #endregion /// <summary> Modified: trunk/Source/StructureMap/InstanceFactory.cs =================================================================== --- trunk/Source/StructureMap/InstanceFactory.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap/InstanceFactory.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -142,6 +142,7 @@ public void Dispose() { + _instances.GetAll().Each(i => i.SafeDispose()); _instances.Clear(); } } Modified: trunk/Source/StructureMap/Pipeline/MainObjectCache.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/MainObjectCache.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap/Pipeline/MainObjectCache.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -25,7 +25,7 @@ var disposable = _objects[key] as IDisposable; _objects.Remove(key); - disposeObject(disposable); + disposable.SafeDispose(); } public object Get(Type pluginType, Instance instance) @@ -59,25 +59,12 @@ { if (@object is Container) return; - disposeObject(@object as IDisposable); + @object.SafeDispose(); }); _objects.Clear(); } } - private void disposeObject(IDisposable disposable) - { - if (disposable != null) - { - try - { - disposable.Dispose(); - } - catch (Exception) - { - } - } - } } } \ No newline at end of file Modified: trunk/Source/StructureMap/Pipeline/ObjectInstance.cs =================================================================== --- trunk/Source/StructureMap/Pipeline/ObjectInstance.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap/Pipeline/ObjectInstance.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -40,6 +40,12 @@ public void Dispose() { + bool isContainer = _object is IContainer; + if (!isContainer) + { + _object.SafeDispose(); + } + _object = null; } Modified: trunk/Source/StructureMap/PipelineGraph.cs =================================================================== --- trunk/Source/StructureMap/PipelineGraph.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap/PipelineGraph.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -55,17 +55,17 @@ public void Dispose() { - if (_factories.ContainsKey(typeof (IContainer))) - { - foreach (Instance instance in _factories[typeof (IContainer)].AllInstances) - { - var disposable = instance as IDisposable; - if (disposable != null) - { - disposable.Dispose(); - } - } - } + //if (_factories.ContainsKey(typeof (IContainer))) + //{ + // foreach (Instance instance in _factories[typeof (IContainer)].AllInstances) + // { + // var disposable = instance as IDisposable; + // if (disposable != null) + // { + // disposable.Dispose(); + // } + // } + //} foreach (var factory in _factories) { Modified: trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs =================================================================== --- trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap/Query/InstanceFactoryTypeConfiguration.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -24,6 +24,7 @@ void IFamily.Eject(Instance instance) { cache.Eject(_pluginType, instance); + instance.SafeDispose(); } object IFamily.Build(Instance instance) Modified: trunk/Source/StructureMap/TypeExtensions.cs =================================================================== --- trunk/Source/StructureMap/TypeExtensions.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap/TypeExtensions.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -19,7 +19,21 @@ list.Add(value); } + public static void SafeDispose(this object target) + { + var disposable = target as IDisposable; + if (disposable == null) return; + try + { + disposable.Dispose(); + } + catch (Exception) + { + } + } + + public static void TryGet<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Action<TValue> action) { Modified: trunk/Source/StructureMap.Testing/Pipeline/ContainerDisposalTester.cs =================================================================== --- trunk/Source/StructureMap.Testing/Pipeline/ContainerDisposalTester.cs 2010-02-04 02:32:53 UTC (rev 335) +++ trunk/Source/StructureMap.Testing/Pipeline/ContainerDisposalTester.cs 2010-02-04 03:17:07 UTC (rev 336) @@ -16,6 +16,35 @@ #endregion [Test] + public void disposing_a_main_container_will_dispose_an_object_injected_into_the_container() + { + var disposable = new C2Yes(); + var container = new Container(x => x.For<C2Yes>().Use(disposable)); + + container.Dispose(); + + disposable.WasDisposed.ShouldBeTrue(); + } + + [Test] + public void main_container_should_dispose_singletons() + { + var container = new Container(x => + { + x.ForSingletonOf<C1Yes>().Use<C1Yes>(); + }); + + var single = container.GetInstance<C1Yes>(); + + container.Dispose(); + + single.WasDisposed.ShouldBeTrue(); + } + + + + + [Test] public void disposing_a_nested_container_does_not_try_to_dispose_objects_created_by_the_parent() { var container = new Container(x => { x.ForSingletonOf<I1>().Use<C1No>(); }); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |