diff --git a/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs b/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs
index 2c4999ba..0ba11b8a 100644
--- a/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs
+++ b/src/Spring/Spring.Aop/Aop/Support/AttributeMatchMethodPointcut.cs
@@ -1,203 +1,213 @@
-#region License
-
-/*
-* Copyright 2002-2004 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
-
-#region Imports
-
-using System;
-using System.Reflection;
-using Spring.Util;
-
-#endregion
-
-namespace Spring.Aop.Support
-{
- ///
- /// implementation that matches methods
- /// that have been decorated with a specified .
- ///
- /// Aleksandar Seovic
- /// Ronald Wildenberg
- [Serializable]
- public class AttributeMatchMethodPointcut : StaticMethodMatcherPointcut
- {
- private Type _attribute;
- private bool _inherit = true;
- private bool _checkInterfaces = false;
-
- ///
- /// Creates a new instance of the
- /// class.
- ///
- public AttributeMatchMethodPointcut()
- {
- }
-
- ///
- /// Creates a new instance of the
- /// class.
- ///
- ///
- /// The to match.
- ///
- public AttributeMatchMethodPointcut(Type attribute)
- : this(attribute, true, false)
- {
- }
-
- ///
- /// Creates a new instance of the
- ///
- /// class.
- ///
- ///
- /// The to match.
- ///
- ///
- /// Flag that controls whether or not the inheritance tree of the
- /// method to be included in the search for the ?
- ///
- public AttributeMatchMethodPointcut(Type attribute, bool inherit)
- : this(attribute, inherit, false)
- {
- }
-
- ///
- /// Creates a new instance of the
- ///
- /// class.
- ///
- ///
- /// The to match.
- ///
- ///
- /// Flag that controls whether or not the inheritance tree of the
- /// method to be included in the search for the ?
- ///
- ///
- /// Flag that controls whether or not interfaces attributes of the
- /// method to be included in the search for the ?
- ///
- public AttributeMatchMethodPointcut(Type attribute, bool inherit, bool checkInterfaces)
- {
- Attribute = attribute;
- Inherit = inherit;
- CheckInterfaces = checkInterfaces;
- }
-
- ///
- /// The to match.
- ///
- ///
- /// If the supplied value is not a that
- /// derives from the class.
- ///
- public virtual Type Attribute
- {
- get { return _attribute; }
- set
- {
- if (value != null)
- {
- if (!typeof (Attribute).IsAssignableFrom(value))
- {
- throw new ArgumentException(
- string.Format(
- "The [{0}] Type must be derived from the [System.Attribute] class.",
- value));
- }
- }
- _attribute = value;
- }
- }
-
- ///
- /// Is the inheritance tree of the method to be included in the search for the
- /// ?
- ///
- ///
- ///
- /// The default is .
- ///
- ///
- public virtual bool Inherit
- {
- get { return _inherit; }
- set { _inherit = value; }
- }
-
- ///
- /// Is the interfaces attributes of the method to be included in the search for theg
- /// ?
- ///
- ///
- ///
- /// The default is .
- ///
- ///
- public virtual bool CheckInterfaces
- {
- get { return _checkInterfaces; }
- set { _checkInterfaces = value; }
- }
-
- ///
- /// Does the supplied satisfy this matcher?
- ///
- /// The candidate method.
- ///
- /// The target (may be ,
- /// in which case the candidate must be taken
- /// to be the 's declaring class).
- ///
- ///
- /// if this this method matches statically.
- ///
- public override bool Matches(MethodInfo method, Type targetType)
- {
- if (method.IsDefined(Attribute, Inherit))
- {
- // Checks whether the attribute is defined on the method or a super definition of the method
- // but does not check attributes on implemented interfaces.
- return true;
- }
- else
- {
- if (CheckInterfaces)
- {
- Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method);
-
- // Also check whether the attribute is defined on a method implemented from an interface.
- // First find all interfaces for the type that contains the method.
- // Next, check each interface for the presence of the attribute on the corresponding
- // method from the interface.
- foreach (Type interfaceType in method.DeclaringType.GetInterfaces())
- {
- MethodInfo intfMethod = interfaceType.GetMethod(method.Name, parameterTypes);
- if (intfMethod != null && intfMethod.IsDefined(Attribute, Inherit))
- {
- return true;
- }
- }
- }
- return false;
- }
- }
- }
+#region License
+
+/*
+* Copyright 2002-2004 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
+
+#region Imports
+
+using System;
+using System.Reflection;
+using Spring.Util;
+
+#endregion
+
+namespace Spring.Aop.Support
+{
+ ///
+ /// implementation that matches methods
+ /// that have been decorated with a specified .
+ ///
+ /// Aleksandar Seovic
+ /// Ronald Wildenberg
+ [Serializable]
+ public class AttributeMatchMethodPointcut : StaticMethodMatcherPointcut
+ {
+ private Type _attribute;
+ private bool _inherit = true;
+ private bool _checkInterfaces = false;
+
+ ///
+ /// Creates a new instance of the
+ /// class.
+ ///
+ public AttributeMatchMethodPointcut()
+ {
+ }
+
+ ///
+ /// Creates a new instance of the
+ /// class.
+ ///
+ ///
+ /// The to match.
+ ///
+ public AttributeMatchMethodPointcut(Type attribute)
+ : this(attribute, true, false)
+ {
+ }
+
+ ///
+ /// Creates a new instance of the
+ ///
+ /// class.
+ ///
+ ///
+ /// The to match.
+ ///
+ ///
+ /// Flag that controls whether or not the inheritance tree of the
+ /// method to be included in the search for the ?
+ ///
+ public AttributeMatchMethodPointcut(Type attribute, bool inherit)
+ : this(attribute, inherit, false)
+ {
+ }
+
+ ///
+ /// Creates a new instance of the
+ ///
+ /// class.
+ ///
+ ///
+ /// The to match.
+ ///
+ ///
+ /// Flag that controls whether or not the inheritance tree of the
+ /// method to be included in the search for the ?
+ ///
+ ///
+ /// Flag that controls whether or not interfaces attributes of the
+ /// method to be included in the search for the ?
+ ///
+ public AttributeMatchMethodPointcut(Type attribute, bool inherit, bool checkInterfaces)
+ {
+ Attribute = attribute;
+ Inherit = inherit;
+ CheckInterfaces = checkInterfaces;
+ }
+
+ ///
+ /// The to match.
+ ///
+ ///
+ /// If the supplied value is not a that
+ /// derives from the class.
+ ///
+ public virtual Type Attribute
+ {
+ get { return _attribute; }
+ set
+ {
+ if (value != null)
+ {
+ if (!typeof (Attribute).IsAssignableFrom(value))
+ {
+ throw new ArgumentException(
+ string.Format(
+ "The [{0}] Type must be derived from the [System.Attribute] class.",
+ value));
+ }
+ }
+ _attribute = value;
+ }
+ }
+
+ ///
+ /// Is the inheritance tree of the method to be included in the search for the
+ /// ?
+ ///
+ ///
+ ///
+ /// The default is .
+ ///
+ ///
+ public virtual bool Inherit
+ {
+ get { return _inherit; }
+ set { _inherit = value; }
+ }
+
+ ///
+ /// Is the interfaces attributes of the method to be included in the search for theg
+ /// ?
+ ///
+ ///
+ ///
+ /// The default is .
+ ///
+ ///
+ public virtual bool CheckInterfaces
+ {
+ get { return _checkInterfaces; }
+ set { _checkInterfaces = value; }
+ }
+
+ ///
+ /// Does the supplied satisfy this matcher?
+ ///
+ /// The candidate method.
+ ///
+ /// The target (may be ,
+ /// in which case the candidate must be taken
+ /// to be the 's declaring class).
+ ///
+ ///
+ /// if this this method matches statically.
+ ///
+ public override bool Matches(MethodInfo method, Type targetType)
+ {
+ if (method.IsDefined(Attribute, Inherit))
+ {
+ // Checks whether the attribute is defined on the method or a super definition of the method
+ // but does not check attributes on implemented interfaces.
+ return true;
+ }
+ else
+ {
+ if (CheckInterfaces)
+ {
+ // Also check whether the attribute is defined on a method implemented from an interface.
+ // First find all interfaces for the type that contains the method.
+ // Next, check each interface for the presence of the attribute on the corresponding
+ // method from the interface.
+ Type[] parameterTypes = ReflectionUtils.GetParameterTypes(method);
+ foreach (Type interfaceType in method.DeclaringType.GetInterfaces())
+ {
+ // The method may be implemented explicitly, so the method name
+ // will include the interface name also
+ string methodName = method.Name;
+ if (methodName.IndexOf('.') != -1)
+ {
+ if (methodName.StartsWith(interfaceType.FullName.Replace('+', '.')))
+ {
+ methodName = methodName.Remove(0, interfaceType.FullName.Length + 1);
+ }
+ }
+
+ MethodInfo intfMethod = interfaceType.GetMethod(methodName, parameterTypes);
+ if (intfMethod != null && intfMethod.IsDefined(Attribute, Inherit))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs
index 690ca913..a42f5594 100644
--- a/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs
+++ b/test/Spring/Spring.Aop.Tests/Aop/Support/AttributeMatchMethodPointcutTests.cs
@@ -179,6 +179,26 @@ namespace Spring.Aop.Support
"but the method from an indirectly implemented interface was, so this must match.");
}
+ ///
+ /// Confirms that methods, explicitly implemented in the derived classes will match
+ ///
+ [Test(Description="SPRNET-1314")]
+ public void MatchesWhenExplicitlyImplemed()
+ {
+ AttributeMatchMethodPointcut cut = new AttributeMatchMethodPointcut();
+ cut.Attribute = typeof(MarkupAttribute);
+ cut.CheckInterfaces = true;
+
+ // Only methods implemented expicitly are marked with attribute
+ foreach (MethodInfo mi in typeof(ExplicitlyImplementingClass).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic))
+ {
+ if (mi.Name.IndexOf('.') == -1) continue;
+ bool matches = cut.Matches(mi, null);
+ Assert.IsTrue(matches, "Explicitly implemented method must match");
+ }
+
+ }
+
#region Helper classes definitions
[AttributeUsage(AttributeTargets.Method)]
@@ -210,6 +230,12 @@ namespace Spring.Aop.Support
void OtherTestMethod();
}
+ private interface AnotherSuperInterface
+ {
+ [Markup]
+ void TestMethod();
+ }
+
private class ImplementingClass : SubInterface
{
public void TestMethod() {}
@@ -223,6 +249,15 @@ namespace Spring.Aop.Support
{
}
+ private class ExplicitlyImplementingClass : SuperInterface, AnotherSuperInterface
+ {
+ void AnotherSuperInterface.TestMethod() { }
+
+ void SuperInterface.TestMethod() { }
+
+ public void TestMethod(string param) {}
+ }
+
#endregion
}
}
\ No newline at end of file