This commit is contained in:
Steve Bohlen
2012-05-02 15:44:08 -04:00
5 changed files with 146 additions and 8 deletions

View File

@@ -1603,11 +1603,11 @@ MyInterface myProxyObject2 = (MyInterface)ctx.GetObject("MyObject");
advice before or after making the target object method call on the target
object.</para>
<para>The inheritance based mechanism creates a dynamic type where that
inherits from the target type. This lets you downcast to the target type
if needed. Please note that in both cases a target method implementation
that calls other methods on the target object will not be advised. To
force inheritance based proxies you should either set the
<para>The inheritance based mechanism creates a dynamic type that inherits
from the target type. This lets you downcast to the target type if needed.
Please note that in both cases a target method implementation that calls
other methods on the target object will not be advised. To force
inheritance based proxies you should either set the
<literal>ProxyTargetType</literal> property of a
<literal>ProxyFactory</literal> to true or set the XML namespace element
<literal>proxy-target-type = true</literal> when using an AOP schema based
@@ -1633,7 +1633,7 @@ MyInterface myProxyObject2 = (MyInterface)ctx.GetObject("MyObject");
described above, all methods that manipulate the state of the object
should be declared as virtual. Otherwise some method invocations get
directed to the private 'target' field member and others to the base
class. Winform object are an example of case where this approach does
class. Winform objects are an example of a case where this approach does
not apply. To address this limitation, a new post-processing mechanism
was introduced in version 1.2 that creates a proxy type without the
private 'target' field. Interception advice is added directly in the

View File

@@ -47,6 +47,8 @@ namespace Spring.Aop.Framework
private const string COMPOSITION_PROXY_TYPE_NAME = "CompositionAopProxy";
private const string DECORATOR_PROXY_TYPE_NAME = "DecoratorAopProxy";
private const string INHERITANCE_PROXY_TYPE_NAME = "InheritanceAopProxy";
/// <summary>
/// Is the supplied <paramref name="objectType"/> an AOP proxy?
@@ -58,7 +60,7 @@ namespace Spring.Aop.Framework
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is an AOP proxy type.</returns>
public static bool IsAopProxyType(Type objectType)
{
return IsCompositionAopProxyType(objectType) || IsDecoratorAopProxyType(objectType);
return IsCompositionAopProxyType(objectType) || IsDecoratorAopProxyType(objectType) || IsInheritanceAopProxyType(objectType);
}
/// <summary>
@@ -75,7 +77,7 @@ namespace Spring.Aop.Framework
/// </returns>
public static bool IsAopProxy(object instance)
{
return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance);
return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance) || IsInheritanceAopProxy(instance);
}
/// <summary>
@@ -130,6 +132,30 @@ namespace Spring.Aop.Framework
return ((objectType != null) && objectType.FullName.StartsWith(DECORATOR_PROXY_TYPE_NAME));
}
/// <summary>
/// Is the supplied <paramref name="instance"/> an inheritance based AOP proxy?
/// </summary>
/// <param name="instance">The instance to be checked.</param>
/// <returns>
/// <see langword="true"/> if the supplied <paramref name="instance"/> is
/// an inheritacne based AOP proxy.
/// </returns>
public static bool IsInheritanceAopProxy(Object instance)
{
return instance != null && IsInheritanceAopProxyType(instance.GetType());
}
/// <summary>
/// Is the supplied <paramref name="objectType"/> an inheritance based AOP proxy type?
/// </summary>
/// <param name="objectType">The type to be checked.</param>
/// <returns><see langword="true"/> if the supplied <paramref name="objectType"/> is an inheritance based AOP proxy type.</returns>
public static bool IsInheritanceAopProxyType(Type objectType)
{
return ((objectType != null) && objectType.FullName.StartsWith(INHERITANCE_PROXY_TYPE_NAME));
}
/// <summary>
/// Gets all of the interfaces that the <see cref="System.Type"/> of the
/// supplied <paramref name="instance"/> implements.
@@ -379,5 +405,6 @@ namespace Spring.Aop.Framework
}
return candidate.GetType();
}
}
}

View File

@@ -0,0 +1,83 @@
using System;
using NUnit.Framework;
using Spring.Aop.Advice;
using Spring.Context.Support;
using Spring.Objects;
using Spring.Objects.Factory.Xml;
namespace Spring.Aop.Framework.DynamicProxy
{
[TestFixture]
public class IsAopProxyTests
{
private TestObject _target;
[SetUp]
public void SetUp()
{
_target = new TestObject("Michael", 23);
}
[Test]
public void TargetIsNotAProxy()
{
Assert.False(AopUtils.IsAopProxy(_target));
Assert.False(AopUtils.IsInheritanceAopProxy(_target));
Assert.False(AopUtils.IsInheritanceAopProxyType(_target.GetType()));
}
[Test]
public void IsCompositionProxy()
{
var pf = new ProxyFactory(typeof(ITestObject), new DebugAdvice());
pf.Target = _target;
Assert.False(pf.ProxyTargetType);
var proxy = (ITestObject)pf.GetProxy();
Assert.True(AopUtils.IsCompositionAopProxy(proxy));
Assert.True(AopUtils.IsAopProxy(proxy));
Assert.IsNotInstanceOf<TestObject>(proxy);
}
[Test]
public void IsDecoratorProxy()
{
var pf = new ProxyFactory(new DebugAdvice());
pf.Target = _target;
pf.ProxyTargetType = true;
var proxy = (TestObject)pf.GetProxy();
Assert.True(AopUtils.IsDecoratorAopProxy(proxy));
Assert.True(AopUtils.IsAopProxy(proxy));
}
[Test]
public void IsInheritanceBasedProxyTypeReturnsFalseForNull()
{
Assert.False(AopUtils.IsInheritanceAopProxyType(null));
}
[Test]
public void IsInheritanceBasedProxyReturnsFalseForNull()
{
Assert.False(AopUtils.IsInheritanceAopProxy(null));
}
[Test]
public void IsInheritanceBasedProxy()
{
using (var ctx = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("IsAopProxyTests.xml", this.GetType())))
{
var proxy = (TestObject)ctx["michael"];
Assert.AreEqual("Michael", proxy.Name);
Assert.True(AopUtils.IsInheritanceAopProxyType(proxy.GetType()));
Assert.True(AopUtils.IsAopProxyType(proxy.GetType()));
Assert.True(AopUtils.IsInheritanceAopProxy(proxy));
Assert.True(AopUtils.IsAopProxy(proxy));
}
}
}
}

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.net/aop">
<object type="Spring.Aop.Framework.AutoProxy.InheritanceBasedAopConfigurer, Spring.Aop">
<property name="ObjectNames">
<list>
<value>michael</value>
</list>
</property>
<property name="InterceptorNames">
<list>
<value>debugInterceptor</value>
</list>
</property>
</object>
<object id="michael" type="Spring.Objects.TestObject, Spring.Core.Tests">
<property name="Age" value="23" />
<property name="Name" value="Michael" />
</object>
<object id="debugInterceptor" type="Spring.Aop.Advice.DebugAdvice, Spring.Aop.Tests" />
</objects>

View File

@@ -153,6 +153,7 @@
<Compile Include="Aop\Framework\DynamicProxy\InheritanceAopProxyTests.cs" />
<Compile Include="Aop\Framework\DynamicProxy\DecoratorAopProxyTests.cs" />
<Compile Include="Aop\Framework\DynamicProxy\DefaultAopProxyFactoryTests.cs" />
<Compile Include="Aop\Framework\DynamicProxy\IsAopProxyTests.cs" />
<Compile Include="Aop\Framework\DynamicProxy\MockTargetSource.cs" />
<Compile Include="Aop\Framework\HashtableCachingAdvisorChainFactoryTests.cs">
<SubType>Code</SubType>
@@ -277,6 +278,7 @@
<EmbeddedResource Include="Data\Spring\Aop\Framework\adapter\withBPPContext.xml" />
<EmbeddedResource Include="Data\Spring\Aop\Framework\adapter\withoutBPPContext.xml" />
<EmbeddedResource Include="Aop\Framework\AutoProxy\advisorAutoProxyCreatorCircularReferencesTests.xml" />
<EmbeddedResource Include="Aop\Framework\DynamicProxy\IsAopProxyTests.xml" />
<Content Include="Data\Spring\Aop\Framework\AutoProxy\advisorAutoProxyCreator.xml" />
<Content Include="Data\Spring\Aop\Framework\AutoProxy\objectNameAutoProxyCreatorTests.xml" />
<Content Include="Data\Spring\Aop\Framework\innerBeanTarget.xml" />