From: <fab...@us...> - 2010-07-31 11:38:11
|
Revision: 5084 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5084&view=rev Author: fabiomaulo Date: 2010-07-31 11:38:05 +0000 (Sat, 31 Jul 2010) Log Message: ----------- Added extension to check if a method is declared by an interface. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectionHelperIsMethodOfTests.cs Modified: trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs 2010-07-31 08:30:17 UTC (rev 5083) +++ trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs 2010-07-31 11:38:05 UTC (rev 5084) @@ -55,6 +55,58 @@ } return ((MemberExpression)property.Body).Member; } + + /// <summary> + /// Check if a method is declared in a given <see cref="System.Type"/>. + /// </summary> + /// <param name="source">The method to check.</param> + /// <param name="realDeclaringType">The where the method is really declared.</param> + /// <returns>True if the method is an implementation of the method declared in <paramref name="realDeclaringType"/>; false otherwise. </returns> + public static bool IsMethodOf(this MethodInfo source, System.Type realDeclaringType) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + if (realDeclaringType == null) + { + throw new ArgumentNullException("realDeclaringType"); + } + var methodDeclaringType = source.DeclaringType; + if(realDeclaringType.Equals(methodDeclaringType)) + { + return true; + } + if (methodDeclaringType.IsGenericType && !methodDeclaringType.IsGenericTypeDefinition && + realDeclaringType.Equals(methodDeclaringType.GetGenericTypeDefinition())) + { + return true; + } + if (realDeclaringType.IsInterface) + { + var declaringTypeInterfaces = methodDeclaringType.GetInterfaces(); + if(declaringTypeInterfaces.Contains(realDeclaringType)) + { + var methodsMap = methodDeclaringType.GetInterfaceMap(realDeclaringType); + if(methodsMap.TargetMethods.Contains(source)) + { + return true; + } + } + if (realDeclaringType.IsGenericTypeDefinition) + { + bool implements = declaringTypeInterfaces + .Where(t => t.IsGenericType && t.GetGenericTypeDefinition().Equals(realDeclaringType)) + .Select(implementedGenericInterface => methodDeclaringType.GetInterfaceMap(implementedGenericInterface)) + .Any(methodsMap => methodsMap.TargetMethods.Contains(source)); + if (implements) + { + return true; + } + } + } + return false; + } } // TODO rename / remove - reflection helper above is better Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-07-31 08:30:17 UTC (rev 5083) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-07-31 11:38:05 UTC (rev 5084) @@ -440,6 +440,7 @@ <Compile Include="Linq\QueryCacheableTests.cs" /> <Compile Include="Linq\QueryReuseTests.cs" /> <Compile Include="Linq\ReadonlyTestCase.cs" /> + <Compile Include="UtilityTest\ReflectionHelperIsMethodOfTests.cs" /> <Compile Include="UtilityTest\ReflectionHelperTest.cs" /> <Compile Include="Linq\RegresstionTests.cs" /> <Compile Include="Linq\SelectionTests.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectionHelperIsMethodOfTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectionHelperIsMethodOfTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/UtilityTest/ReflectionHelperIsMethodOfTests.cs 2010-07-31 11:38:05 UTC (rev 5084) @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using NHibernate.Linq; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.UtilityTest +{ + public class ReflectionHelperIsMethodOfTests + { + [Test] + public void WhenNullMethodInfoThenThrows() + { + ((MethodInfo) null).Executing(mi => mi.IsMethodOf(typeof (Object))).Throws<ArgumentNullException>(); + } + + [Test] + public void WhenNullTypeThenThrows() + { + ReflectionHelper.GetMethodDefinition<List<int>>(t => t.Contains(5)).Executing(mi => mi.IsMethodOf(null)).Throws<ArgumentNullException>(); + } + + [Test] + public void WhenDeclaringTypeMatchThenTrue() + { + ReflectionHelper.GetMethodDefinition<List<int>>(t => t.Contains(5)).IsMethodOf(typeof(List<int>)).Should().Be.True(); + } + + private class MyCollection: List<int> + { + + } + + [Test] + public void WhenCustomTypeMatchThenTrue() + { + ReflectionHelper.GetMethodDefinition<MyCollection>(t => t.Contains(5)).IsMethodOf(typeof(List<int>)).Should().Be.True(); + } + + [Test] + public void WhenTypeIsGenericDefinitionAndMatchThenTrue() + { + ReflectionHelper.GetMethodDefinition<List<int>>(t => t.Contains(5)).IsMethodOf(typeof(List<>)).Should().Be.True(); + } + + [Test] + public void WhenTypeIsGenericImplementedInterfaceAndMatchThenTrue() + { + var containsMethodDefinition = ReflectionHelper.GetMethodDefinition<List<int>>(t => t.Contains(5)); + containsMethodDefinition.IsMethodOf(typeof(ICollection<int>)).Should().Be.True(); + } + + [Test] + public void WhenTypeIsGenericImplementedInterfaceAndMatchGenericInterfaceDefinitionThenTrue() + { + var containsMethodDefinition = ReflectionHelper.GetMethodDefinition<List<int>>(t => t.Contains(5)); + containsMethodDefinition.IsMethodOf(typeof(ICollection<>)).Should().Be.True(); + } + + [Test] + public void WhenNoMatchThenFalse() + { + ReflectionHelper.GetMethodDefinition<List<int>>(t => t.Contains(5)).IsMethodOf(typeof(IEnumerable<>)).Should().Be.False(); + } + + private abstract class MyAbstractClass<T> + { + public abstract T MyMethod(); + } + + private class MyClass : MyAbstractClass<int> + { + public override int MyMethod() {return 0;} + } + + [Test] + public void WhenTypeIsGenericImplementedAbstractAndMatchThenTrue() + { + var containsMethodDefinition = ReflectionHelper.GetMethodDefinition<MyClass>(t => t.MyMethod()); + containsMethodDefinition.IsMethodOf(typeof(MyAbstractClass<int>)).Should().Be.True(); + } + + [Test] + public void WhenTypeIsGenericImplementedAbstractAndMatchGenericInterfaceDefinitionThenTrue() + { + var containsMethodDefinition = ReflectionHelper.GetMethodDefinition<MyClass>(t => t.MyMethod()); + containsMethodDefinition.IsMethodOf(typeof(MyAbstractClass<>)).Should().Be.True(); + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |