diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs index e7af9d00..62f4af3b 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs @@ -326,6 +326,42 @@ namespace Spring.Objects.Factory.Support return null; } + /// + /// Apply s + /// to the given existing object instance, invoking their + /// + /// methods. + /// + /// + /// The existing object instance. + /// + /// + /// The name of the object. + /// + /// + public virtual void ApplyObjectPostProcessBeforeDestruction(object instance, string name) + { + log.Debug(m => m("Invoking PostProcessBeforeDestruction after IDisposal of object '" + name + "'")); + + foreach (IObjectPostProcessor objectProcessor in ObjectPostProcessors) + { + if (objectProcessor is IDestructionAwareObjectPostProcessor) + { + try + { + ((IDestructionAwareObjectPostProcessor)objectProcessor).PostProcessBeforeDestruction(instance, name); + } + catch (Exception ex) + { + log.ErrorFormat( + string.Format("Error during execution of {0}.PostProcessBeforeDestruction for object {1}", + objectProcessor.GetType().Name, name), ex); + } + } + } + } + + /// /// Apply the given property values, resolving any runtime references /// to other objects in this object factory. @@ -1402,26 +1438,12 @@ namespace Spring.Objects.Factory.Support /// protected override void DestroyObject(string name, object target) { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Destroying dependant objects for object '" + name + "'"); - } - - #endregion + log.Debug(m => m("Destroying dependant objects for object '{0}", name)); DestroyDependantObjects(name); if (target is IDisposable) { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug(string.Format(CultureInfo.InvariantCulture, "Calling Dispose () on object with name '{0}'.", name)); - } - - #endregion + log.Debug(m => m(string.Format(CultureInfo.InvariantCulture, "Calling Dispose() on object with name '{0}'.", name))); try { @@ -1429,24 +1451,16 @@ namespace Spring.Objects.Factory.Support } catch (Exception ex) { - #region Instrumentation - log.Error("Destroy() on object with name '" + name + "' threw an exception.", ex); - - #endregion } } + + ApplyObjectPostProcessBeforeDestruction(target, name); + RootObjectDefinition rootDefinition = GetMergedObjectDefinition(name, false); if (rootDefinition != null && StringUtils.HasText(rootDefinition.DestroyMethodName)) { - #region Instrumentation - - if (log.IsDebugEnabled) - { - log.Debug("Calling custom destroy method '" + rootDefinition.DestroyMethodName + "' on object with name '" + name + "'."); - } - - #endregion + log.Debug(m => m("Calling custom destroy method '{0}' on object with name '{1}'.", rootDefinition.DestroyMethodName, name)); InvokeCustomDestroyMethod(name, target, rootDefinition.DestroyMethodName); } diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DestructionAwareObjectPostProcessorTest.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DestructionAwareObjectPostProcessorTest.cs new file mode 100644 index 00000000..1b953ee3 --- /dev/null +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/DestructionAwareObjectPostProcessorTest.cs @@ -0,0 +1,85 @@ +#region License + +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#endregion + +using NUnit.Framework; +using Spring.Context.Support; +using Spring.Objects.Factory.Support; + +namespace Spring.Objects.Factory.Config +{ + [TestFixture] + public class DestructionAwareObjectPostProcessorTest + { + private GenericApplicationContext _context; + + [SetUp] + public void Setup() + { + _context = new GenericApplicationContext(); + + var objectDefinition = new RootObjectDefinition(typeof(DestructionPostProcessor)); + objectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE; + _context.ObjectFactory.RegisterObjectDefinition("DestructionPostProcessor", objectDefinition); + + var objectDef = new RootObjectDefinition(typeof(DestroyTester)); + _context.ObjectFactory.RegisterObjectDefinition("DestroyTester", objectDef); + + _context.Refresh(); + } + + [Test] + public void PostProcessBeforeDestructionIsCalled() + { + var testObj = _context.GetObject("DestroyTester"); + _context.Dispose(); + + Assert.That(DestructionTester.MethodCalled, Is.EqualTo(1)); + } + } + + public class DestructionPostProcessor : IDestructionAwareObjectPostProcessor + { + public void PostProcessBeforeDestruction(object instance, string name) + { + if (instance.GetType() == typeof(DestroyTester)) + DestructionTester.MethodCalled++; + } + + public object PostProcessBeforeInitialization(object instance, string name) + { + return instance; + } + + public object PostProcessAfterInitialization(object instance, string objectName) + { + return instance; + } + } + + public class DestroyTester + { + + } + + public static class DestructionTester + { + public static int MethodCalled { get; set; } + } +} diff --git a/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj b/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj index 0c4a138c..85989c54 100644 --- a/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj +++ b/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2008.csproj @@ -325,6 +325,7 @@ + diff --git a/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2010.csproj b/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2010.csproj index 80c70a18..28684fe1 100644 --- a/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2010.csproj +++ b/test/Spring/Spring.Core.Tests/Spring.Core.Tests.2010.csproj @@ -327,6 +327,7 @@ +