diff --git a/doc/reference/src/aop.xml b/doc/reference/src/aop.xml index a31a25c9..bcb819b8 100644 --- a/doc/reference/src/aop.xml +++ b/doc/reference/src/aop.xml @@ -1603,11 +1603,11 @@ MyInterface myProxyObject2 = (MyInterface)ctx.GetObject("MyObject"); advice before or after making the target object method call on the target object. - 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 + 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 ProxyTargetType property of a ProxyFactory to true or set the XML namespace element proxy-target-type = true 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 diff --git a/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs b/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs index 3ceb7a54..6a489af0 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/AopUtils.cs @@ -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"; /// /// Is the supplied an AOP proxy? @@ -58,7 +60,7 @@ namespace Spring.Aop.Framework /// if the supplied is an AOP proxy type. public static bool IsAopProxyType(Type objectType) { - return IsCompositionAopProxyType(objectType) || IsDecoratorAopProxyType(objectType); + return IsCompositionAopProxyType(objectType) || IsDecoratorAopProxyType(objectType) || IsInheritanceAopProxyType(objectType); } /// @@ -75,7 +77,7 @@ namespace Spring.Aop.Framework /// public static bool IsAopProxy(object instance) { - return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance); + return IsCompositionAopProxy(instance) || IsDecoratorAopProxy(instance) || IsInheritanceAopProxy(instance); } /// @@ -130,6 +132,30 @@ namespace Spring.Aop.Framework return ((objectType != null) && objectType.FullName.StartsWith(DECORATOR_PROXY_TYPE_NAME)); } + + /// + /// Is the supplied an inheritance based AOP proxy? + /// + /// The instance to be checked. + /// + /// if the supplied is + /// an inheritacne based AOP proxy. + /// + public static bool IsInheritanceAopProxy(Object instance) + { + return instance != null && IsInheritanceAopProxyType(instance.GetType()); + } + + /// + /// Is the supplied an inheritance based AOP proxy type? + /// + /// The type to be checked. + /// if the supplied is an inheritance based AOP proxy type. + public static bool IsInheritanceAopProxyType(Type objectType) + { + return ((objectType != null) && objectType.FullName.StartsWith(INHERITANCE_PROXY_TYPE_NAME)); + } + /// /// Gets all of the interfaces that the of the /// supplied implements. @@ -379,5 +405,6 @@ namespace Spring.Aop.Framework } return candidate.GetType(); } + } } \ No newline at end of file diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/IsAopProxyTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/IsAopProxyTests.cs new file mode 100644 index 00000000..29e8afa1 --- /dev/null +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/IsAopProxyTests.cs @@ -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(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)); + } + } + } +} \ No newline at end of file diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/IsAopProxyTests.xml b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/IsAopProxyTests.xml new file mode 100644 index 00000000..6b15132a --- /dev/null +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/IsAopProxyTests.xml @@ -0,0 +1,26 @@ + + + + + + + michael + + + + + debugInterceptor + + + + + + + + + + + + diff --git a/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj b/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj index 7d895ddd..1aeacff6 100644 --- a/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj +++ b/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj @@ -153,6 +153,7 @@ + Code @@ -277,6 +278,7 @@ +