From: <fab...@us...> - 2011-04-28 22:49:48
|
Revision: 5787 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5787&view=rev Author: fabiomaulo Date: 2011-04-28 22:49:42 +0000 (Thu, 28 Apr 2011) Log Message: ----------- GetMemberFromReflectedType implemented Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/GetMemberFromReflectedTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs 2011-04-28 18:47:30 UTC (rev 5786) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs 2011-04-28 22:49:42 UTC (rev 5787) @@ -420,6 +420,61 @@ } /// <summary> + /// Given a property or a field try to get the member from a given possible inherited type. + /// </summary> + /// <param name="member">The member to find.</param> + /// <param name="reflectedType">The type where find the member.</param> + /// <returns>The member from the reflected-type or the original <paramref name="member"/> where the <paramref name="member"/> is not accessible from <paramref name="reflectedType"/>.</returns> + public static MemberInfo GetMemberFromReflectedType(this MemberInfo member, System.Type reflectedType) + { + if (member == null) + { + throw new ArgumentNullException("member"); + } + if (reflectedType == null) + { + throw new ArgumentNullException("reflectedType"); + } + var field = member as FieldInfo; + if (field != null && field.IsPrivate) + { + return member; + } + var property = member as PropertyInfo; + if (property != null) + { + var propertyGetter = property.GetGetMethod(true); + if (propertyGetter.IsPrivate) + { + return member; + } + if (property.DeclaringType.IsInterface) + { + System.Type[] interfaces = reflectedType.GetInterfaces(); + var @interface = property.DeclaringType; + if (!interfaces.Contains(@interface)) + { + return member; + } + var reflectedCandidateProps = reflectedType.GetProperties(PropertiesOfClassHierarchy); + InterfaceMapping memberMap = reflectedType.GetInterfaceMap(@interface); + for (int i = 0; i < memberMap.TargetMethods.Length; i++) + { + if (memberMap.InterfaceMethods[i] == propertyGetter) + { + return reflectedCandidateProps.Single(pi => pi.GetGetMethod(true) == memberMap.TargetMethods[i]); + } + } + return member; + } + } + var reflectedTypeProperties = reflectedType.GetProperties(PropertiesOfClassHierarchy); + var members = reflectedTypeProperties.Cast<MemberInfo>().Concat(reflectedType.GetFields(PropertiesOfClassHierarchy)); + var result = members.FirstOrDefault(m=> m.Name.Equals(member.Name) && m.GetPropertyOrFieldType().Equals(member.GetPropertyOrFieldType())); + return result ?? member; + } + + /// <summary> /// Try to find a property or field from a given type. /// </summary> /// <param name="source">The type</param> Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/GetMemberFromReflectedTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/GetMemberFromReflectedTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/GetMemberFromReflectedTest.cs 2011-04-28 22:49:42 UTC (rev 5787) @@ -0,0 +1,133 @@ +using System; +using System.Reflection; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.TypeExtensionsTests +{ + public class GetMemberFromReflectedTest + { + private const BindingFlags PrivateMembersFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly; + + private class MyClass + { + private int pField; + private int PrivateProperty { get; set; } + public int AnotherProperty { get; set; } + protected int ProtectedProperty { get; set; } + private int Method() { return 0; } + } + + private class Inherited : MyClass + { + private int pField; + private int PrivateProperty { get; set; } + } + + private interface IInterface + { + int Something { get; set; } + int SomethingElse { get; set; } + } + + private class MyClassWithExplicitImpl : IInterface + { + int IInterface.Something + { + get + { + throw new System.NotImplementedException(); + } + set + { + throw new System.NotImplementedException(); + } + } + + public int SomethingElse + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + } + + [Test] + public void WhenNullMemberThenThrows() + { + Executing.This(() => ((MemberInfo)null).GetMemberFromReflectedType(typeof(MyClass))).Should().Throw<ArgumentNullException>(); + } + + [Test] + public void WhenNullTypeThenThrows() + { + Executing.This(() => typeof(MyClassWithExplicitImpl).GetProperty("SomethingElse").GetMemberFromReflectedType(null)).Should().Throw<ArgumentNullException>(); + } + + [Test] + public void WhenNotExistentThenOriginal() + { + var propertyInfo = typeof(MyClassWithExplicitImpl).GetProperty("SomethingElse"); + propertyInfo.GetMemberFromReflectedType(typeof(object)).Should().Be(propertyInfo); + } + + [Test] + public void WhenNotAccessibleFieldThenOriginal() + { + var memberInfo = typeof(MyClass).GetField("pField", PrivateMembersFlags); + memberInfo.GetMemberFromReflectedType(typeof(Inherited)).Should().Be(memberInfo); + } + + [Test] + public void WhenNotAccessiblePropertyThenOriginal() + { + var memberInfo = typeof(MyClass).GetProperty("PrivateProperty", PrivateMembersFlags); + memberInfo.GetMemberFromReflectedType(typeof(Inherited)).Should().Be(memberInfo); + } + + [Test] + public void WhenAccessiblePropertyThenReflected() + { + var memberInfo = typeof(MyClass).GetProperty("ProtectedProperty", PrivateMembersFlags); + var result = memberInfo.GetMemberFromReflectedType(typeof(Inherited)); + result.ReflectedType.Should().Be(typeof(Inherited)); + result.DeclaringType.Should().Be(typeof(MyClass)); + } + + [Test] + public void WhenPrivateFieldOnInheritedThenFindItOnInherited() + { + var memberInfo = typeof(Inherited).GetField("pField", PrivateMembersFlags); + var result = memberInfo.GetMemberFromReflectedType(typeof(MyClass)); + result.ReflectedType.Should().Be(typeof(Inherited)); + result.DeclaringType.Should().Be(typeof(Inherited)); + } + + [Test] + public void WhenPublicPropertyOfBaseOnInheritedThenFindItOnInherited() + { + var memberInfo = typeof(MyClass).GetProperty("AnotherProperty"); + var result = memberInfo.GetMemberFromReflectedType(typeof(Inherited)); + result.ReflectedType.Should().Be(typeof(Inherited)); + result.DeclaringType.Should().Be(typeof(MyClass)); + } + + [Test] + public void WhenPropertyOfInterfaceThenFindItOnClass() + { + var memberInfo = typeof(IInterface).GetProperty("SomethingElse"); + var result = memberInfo.GetMemberFromReflectedType(typeof(MyClassWithExplicitImpl)); + result.DeclaringType.Should().Be(typeof(MyClassWithExplicitImpl)); + result.ReflectedType.Should().Be(typeof(MyClassWithExplicitImpl)); + } + + [Test] + public void WhenPropertyOfExplicitInterfaceThenFindItOnClass() + { + var memberInfo = typeof(IInterface).GetProperty("Something"); + var result = memberInfo.GetMemberFromReflectedType(typeof(MyClassWithExplicitImpl)); + result.DeclaringType.Should().Be(typeof(MyClassWithExplicitImpl)); + result.ReflectedType.Should().Be(typeof(MyClassWithExplicitImpl)); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-28 18:47:30 UTC (rev 5786) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-28 22:49:42 UTC (rev 5787) @@ -612,6 +612,7 @@ <Compile Include="MappingByCode\TypeExtensionsTests\GetFirstImplementorConcreteClassesTest.cs" /> <Compile Include="MappingByCode\TypeExtensionsTests\GetFirstImplementorTest.cs" /> <Compile Include="MappingByCode\TypeExtensionsTests\GetMemberFromInterfacesTest.cs" /> + <Compile Include="MappingByCode\TypeExtensionsTests\GetMemberFromReflectedTest.cs" /> <Compile Include="MappingByCode\TypeExtensionsTests\GetPropertyOrFieldMatchingNameTest.cs" /> <Compile Include="MappingByCode\TypeExtensionsTests\TypeExtensionsTest.cs" /> <Compile Include="MappingByCode\TypeNameUtilTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |