diff --git a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs index 7818d6c6..5df94fbf 100644 --- a/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs +++ b/src/Spring/Spring.Aop/Aop/Framework/DynamicProxy/InheritanceAopProxyTypeBuilder.cs @@ -201,7 +201,7 @@ namespace Spring.Aop.Framework.DynamicProxy MemberInfo[] matchingMethods = targetType.FindMembers( MemberTypes.Method, - BindingFlags.Instance | BindingFlags.Public, + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria), searchCriteria); diff --git a/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs b/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs index 78d97f2e..d9206928 100644 --- a/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs +++ b/src/Spring/Spring.Core/Proxy/AbstractProxyTypeBuilder.cs @@ -851,8 +851,7 @@ namespace Spring.Proxy IDictionary methodMap = new Hashtable(); IList finalMethods = new ArrayList(); - BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; - + BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic; if (declaredMembersOnly) { bindingFlags |= BindingFlags.DeclaredOnly; @@ -862,7 +861,10 @@ namespace Spring.Proxy MethodInfo[] methods = type.GetMethods(bindingFlags); foreach (MethodInfo method in methods) { - if (method.IsVirtual && !method.IsFinal) + MethodAttributes memberAccess = method.Attributes & MethodAttributes.MemberAccessMask; + + if (method.IsVirtual && !method.IsFinal && !method.Name.Equals("Finalize") + && (memberAccess == MethodAttributes.Public || memberAccess == MethodAttributes.Family || memberAccess == MethodAttributes.FamORAssem)) { MethodBuilder methodBuilder = proxyMethodBuilder.BuildProxyMethod(method, null); ApplyMethodAttributes(methodBuilder, method); diff --git a/src/Spring/Spring.Core/Util/Properties.cs b/src/Spring/Spring.Core/Util/Properties.cs index 3d466a0f..ed8207f7 100644 --- a/src/Spring/Spring.Core/Util/Properties.cs +++ b/src/Spring/Spring.Core/Util/Properties.cs @@ -128,7 +128,7 @@ namespace Spring.Util while ((line = textReader.ReadLine()) != null) { line = RemoveLeadingWhitespace(line); - if (line != null && Comments.IndexOf(line[0]) == -1) + if (line != null && line.Length>0 && Comments.IndexOf(line[0]) == -1) { if (!isContinuation) { diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs index a80a24da..4564a005 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/DecoratorAopProxyTests.cs @@ -120,6 +120,54 @@ namespace Spring.Aop.Framework.DynamicProxy Assert.AreEqual(3, ni.Count); } + [Test] + public void InterceptProtectedVirtualMethod() + { + DoesNotImplementInterfaceTestObject target = new DoesNotImplementInterfaceTestObject(); + target.Name = "Bruno"; + mockTargetSource.SetTarget(target); + + NopInterceptor ni = new NopInterceptor(); + + AdvisedSupport advised = new AdvisedSupport(); + advised.TargetSource = mockTargetSource; + advised.AddAdvice(ni); + + DoesNotImplementInterfaceTestObject proxy = CreateProxy(advised) as DoesNotImplementInterfaceTestObject; + Assert.IsNotNull(proxy); + + // GetName() calls underlying protected "GetNameInternal()" which calls get_Name + Assert.AreEqual(target.Name, proxy.GetName(), "Incorrect name"); + target.Name = "Bruno Baia"; + Assert.AreEqual("Bruno Baia", proxy.GetName(), "Incorrect name"); + + Assert.AreEqual(2, ni.Count); + } + + [Test] + public void InterceptInheritedVirtualMethods() + { + DoesNotImplementInterfaceTestObject target = new DerivedDoesNotImplementInterfaceTestObject(); + target.Name = "Bruno"; + mockTargetSource.SetTarget(target); + + NopInterceptor ni = new NopInterceptor(); + + AdvisedSupport advised = new AdvisedSupport(); + advised.TargetSource = mockTargetSource; + advised.AddAdvice(ni); + + DoesNotImplementInterfaceTestObject proxy = CreateProxy(advised) as DoesNotImplementInterfaceTestObject; + Assert.IsNotNull(proxy); + + // GetName() calls underlying protected "GetNameInternal()" which calls get_Name + Assert.AreEqual(target.Name, proxy.GetName(), "Incorrect name"); + proxy.Name = "Bruno Baia"; + Assert.AreEqual("Bruno Baia", proxy.Name, "Incorrect name"); + + Assert.AreEqual(3, ni.Count); + } + [Test] public void CannotInterceptFinalMethodThatDoesNotBelongToAnInterface() { @@ -343,8 +391,23 @@ namespace Spring.Aop.Framework.DynamicProxy get { return _location; } set { _location = value; } } + + // protected virtual method + protected virtual string GetNameInternal() + { + return this.Name; + } + + // public final method calling protected + public string GetName() + { + return GetNameInternal(); + } } + public class DerivedDoesNotImplementInterfaceTestObject : DoesNotImplementInterfaceTestObject + {} + #endregion } } diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs index 54122a4c..cd48f712 100644 --- a/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs +++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/DynamicProxy/InheritanceAopProxyTests.cs @@ -175,6 +175,24 @@ namespace Spring.Aop.Framework.DynamicProxy Assert.AreEqual(3, ni.Count); } + [Test] + public void DoesNotInterceptInternalMethod() + { + NopInterceptor ni = new NopInterceptor(); + + AdvisedSupport advised = new AdvisedSupport(); + advised.Target = new InheritanceTestObject(); + advised.AddAdvice(ni); + + object proxy = CreateProxy(advised); + //DynamicProxyManager.SaveAssembly(); + + Assert.IsTrue(proxy is InheritanceTestObject); + InheritanceTestObject proxiedClass = proxy as InheritanceTestObject; + proxiedClass.InternalToDo(); + Assert.AreEqual(0, ni.Count); + } + [Test] public void InterceptVirtualMethodThatBelongsToAnInterface() { @@ -241,23 +259,43 @@ namespace Spring.Aop.Framework.DynamicProxy Assert.AreEqual(2, proxiedClass.Value); } - //[Test] - //public void InterceptProtectedMethod() - //{ - // NopInterceptor ni = new NopInterceptor(); + [Test] + public void InterceptProtectedMethod() + { + NopInterceptor ni = new NopInterceptor(); - // AdvisedSupport advised = new AdvisedSupport(); - // advised.Target = new InheritanceTestObject(); - // advised.AddAdvice(ni); + AdvisedSupport advised = new AdvisedSupport(); + advised.Target = new InheritanceTestObject(); + advised.AddAdvice(ni); - // object proxy = CreateProxy(advised); - // //DynamicProxyManager.SaveAssembly(); + object proxy = CreateProxy(advised); + //DynamicProxyManager.SaveAssembly(); - // Assert.IsTrue(proxy is InheritanceTestObject); - // InheritanceTestObject proxiedClass = proxy as InheritanceTestObject; - // proxiedClass.Todo(); - // Assert.AreEqual(1, ni.Count); - //} + Assert.IsTrue(proxy is InheritanceTestObject); + InheritanceTestObject proxiedClass = proxy as InheritanceTestObject; + proxiedClass.Todo(); + Assert.AreEqual(1, ni.Count); + } + + [Test] + public void InterceptInheritedMethods() + { + NopInterceptor ni = new NopInterceptor(); + + AdvisedSupport advised = new AdvisedSupport(); + advised.Target = new InheritanceTestObject(); + advised.AddAdvice(ni); + + object proxy = CreateProxy(advised); + //DynamicProxyManager.SaveAssembly(); + + Assert.IsTrue(proxy is InheritanceTestObject); + InheritanceTestObject proxiedClass = proxy as InheritanceTestObject; + proxiedClass.Todo(); + proxiedClass.Name = "Erich"; + Assert.AreEqual("Erich", proxiedClass.Name); + Assert.AreEqual(3, ni.Count); + } } #region Helper Classes @@ -336,7 +374,20 @@ namespace Spring.Aop.Framework.DynamicProxy { } + + internal virtual void InternalToDo() + { + + } + + internal protected virtual void InternalProtectedToDo() + { + + } } + public class DerivedInheritanceTestObject : InheritanceTestObject + {} + #endregion } \ No newline at end of file