Merge pull request #24 from thomast74/SPRNET-1518

SPRNET-1518 PostProcessors that implement IDestructionAwareObjectPostPro...
This commit is contained in:
Steve Bohlen
2012-09-13 06:40:05 -07:00
4 changed files with 130 additions and 28 deletions

View File

@@ -326,6 +326,42 @@ namespace Spring.Objects.Factory.Support
return null;
}
/// <summary>
/// Apply <see cref="Spring.Objects.Factory.Config.IDestructionAwareObjectPostProcessor"/>s
/// to the given existing object instance, invoking their
/// <see cref="Spring.Objects.Factory.Config.IDestructionAwareObjectPostProcessor.PostProcessBeforeDestruction"/>
/// methods.
/// </summary>
/// <param name="instance">
/// The existing object instance.
/// </param>
/// <param name="name">
/// The name of the object.
/// </param>
/// <seealso cref="Spring.Objects.Factory.Config.IDestructionAwareObjectPostProcessor.PostProcessBeforeDestruction"/>
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);
}
}
}
}
/// <summary>
/// Apply the given property values, resolving any runtime references
/// to other objects in this object factory.
@@ -1402,26 +1438,15 @@ namespace Spring.Objects.Factory.Support
/// </param>
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);
ApplyObjectPostProcessBeforeDestruction(target, 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 +1454,14 @@ namespace Spring.Objects.Factory.Support
}
catch (Exception ex)
{
#region Instrumentation
log.Error("Destroy() on object with name '" + name + "' threw an exception.", ex);
#endregion
}
}
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);
}

View File

@@ -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; }
}
}

View File

@@ -325,6 +325,7 @@
<Compile Include="Objects\Factory\Config\ConnectionStringsVariableSourceTests.cs" />
<Compile Include="Objects\Factory\Config\ConfigurableVariableSourceTests.cs" />
<Compile Include="Objects\Factory\Config\DelegateObjectFactoryConfigurerTests.cs" />
<Compile Include="Objects\Factory\Config\DestructionAwareObjectPostProcessorTest.cs" />
<Compile Include="Objects\Factory\Config\DictionaryVariableSourceTests.cs" />
<Compile Include="Objects\Factory\Config\ObjectDefinitionVisitorTests.cs" />
<Compile Include="Objects\Factory\Config\ResourceHandlerConfigurerTests.cs" />

View File

@@ -327,6 +327,7 @@
<Compile Include="Objects\Factory\Config\ConnectionStringsVariableSourceTests.cs" />
<Compile Include="Objects\Factory\Config\ConfigurableVariableSourceTests.cs" />
<Compile Include="Objects\Factory\Config\DelegateObjectFactoryConfigurerTests.cs" />
<Compile Include="Objects\Factory\Config\DestructionAwareObjectPostProcessorTest.cs" />
<Compile Include="Objects\Factory\Config\DictionaryVariableSourceTests.cs" />
<Compile Include="Objects\Factory\Config\ObjectDefinitionVisitorTests.cs" />
<Compile Include="Objects\Factory\Config\ResourceHandlerConfigurerTests.cs" />