From: <fab...@us...> - 2011-04-28 18:47:39
|
Revision: 5786 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5786&view=rev Author: fabiomaulo Date: 2011-04-28 18:47:30 +0000 (Thu, 28 Apr 2011) Log Message: ----------- by-code: Preparing to add new API for private/protected properties/fields 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/GetPropertyOrFieldMatchingNameTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs 2011-04-28 12:43:58 UTC (rev 5785) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/TypeExtensions.cs 2011-04-28 18:47:30 UTC (rev 5786) @@ -9,8 +9,9 @@ { public static class TypeExtensions { - private const BindingFlags PublicPropertiesOfClassHierarchy = + private const BindingFlags PropertiesOfClassHierarchy = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy; + private const BindingFlags PropertiesOrFieldOfClass = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly; public static IEnumerable<System.Type> GetBaseTypes(this System.Type type) { @@ -410,12 +411,97 @@ public static bool HasPublicPropertyOf(this System.Type source, System.Type typeOfProperty) { - return GetFirstPropertyOfType(source, typeOfProperty, PublicPropertiesOfClassHierarchy) != null; + return GetFirstPropertyOfType(source, typeOfProperty, PropertiesOfClassHierarchy) != null; } public static bool HasPublicPropertyOf(this System.Type source, System.Type typeOfProperty, Func<PropertyInfo, bool> acceptPropertyClauses) { - return GetFirstPropertyOfType(source, typeOfProperty, PublicPropertiesOfClassHierarchy, acceptPropertyClauses) != null; + return GetFirstPropertyOfType(source, typeOfProperty, PropertiesOfClassHierarchy, acceptPropertyClauses) != null; } + + /// <summary> + /// Try to find a property or field from a given type. + /// </summary> + /// <param name="source">The type</param> + /// <param name="memberName">The property or field name.</param> + /// <returns> + /// A <see cref="PropertyInfo"/> or a <see cref="FieldInfo"/> where the member is found; null otherwise. + /// </returns> + /// <remarks> + /// Where found the member is returned always from the declaring type. + /// </remarks> + public static MemberInfo GetPropertyOrFieldMatchingName(this System.Type source, string memberName) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + if (memberName == null) + { + return null; + } + var nameToFind = memberName.Trim(); + var members = source.GetPropertiesOfHierarchy().Concat(source.GetFieldsOfHierarchy()).Concat(source.GetPropertiesOfInterfacesImplemented()); + return members.FirstOrDefault(x => x.Name == nameToFind); + } + + private static IEnumerable<MemberInfo> GetPropertiesOfInterfacesImplemented(this System.Type source) + { + if (source.IsInterface) + { + foreach (var interfaceProperty in source.GetInterfaceProperties()) + { + yield return interfaceProperty; + } + yield break; + } + foreach (var @interface in source.GetInterfaces()) + { + foreach (var interfaceProperty in @interface.GetInterfaceProperties()) + { + yield return interfaceProperty; + } + } + } + + private static IEnumerable<MemberInfo> GetPropertiesOfHierarchy(this System.Type type) + { + if(type.IsInterface) + { + yield break; + } + System.Type analizing = type; + while (analizing != null && analizing != typeof(object)) + { + foreach (PropertyInfo propertyInfo in analizing.GetProperties(PropertiesOrFieldOfClass)) + { + yield return propertyInfo; + } + analizing = analizing.BaseType; + } + } + + private static IEnumerable<MemberInfo> GetFieldsOfHierarchy(this System.Type type) + { + if (type.IsInterface) + { + yield break; + } + System.Type analizing = type; + while (analizing != null && analizing != typeof(object)) + { + foreach (FieldInfo fieldInfo in GetUserDeclaredFields(analizing)) + { + yield return fieldInfo; + } + analizing = analizing.BaseType; + } + } + + private static IEnumerable<FieldInfo> GetUserDeclaredFields(System.Type type) + { + // can't find another way to exclude fields generated by the compiler (for both auto-properties and anonymous-types) + return type.GetFields(PropertiesOrFieldOfClass).Where(x => !x.Name.StartsWith("<")); + } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/GetPropertyOrFieldMatchingNameTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/GetPropertyOrFieldMatchingNameTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/TypeExtensionsTests/GetPropertyOrFieldMatchingNameTest.cs 2011-04-28 18:47:30 UTC (rev 5786) @@ -0,0 +1,178 @@ +using System; +using System.Reflection; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; +namespace NHibernate.Test.MappingByCode.TypeExtensionsTests +{ + public class GetPropertyOrFieldMatchingNameTest + { + private class MyClass + { + private int pField; + private int PrivateProperty { get; set; } + private int AnotherPrivateProperty { 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 WhenNullTypeThenThrows() + { + Executing.This(() => ((System.Type)null).GetPropertyOrFieldMatchingName("A")).Should().Throw<ArgumentNullException>(); + } + + [Test] + public void WhenAskNullThenNull() + { + typeof(MyClass).GetPropertyOrFieldMatchingName(null).Should().Be.Null(); + } + + [Test] + public void WhenAskNotExistentThenNull() + { + typeof(MyClass).GetPropertyOrFieldMatchingName("NotExistent").Should().Be.Null(); + } + + [Test] + public void WhenAskPrivateFieldThenFindIt() + { + var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName("pField"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("pField"); + memberInfo.Should().Be.InstanceOf<FieldInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass)); + } + + [Test] + public void WhenAskPrivateFieldWithBlanksThenFindIt() + { + var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName(" pField "); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("pField"); + memberInfo.Should().Be.InstanceOf<FieldInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass)); + } + + [Test] + public void WhenAskPrivatePropertyThenFindIt() + { + var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName("PrivateProperty"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("PrivateProperty"); + memberInfo.Should().Be.InstanceOf<PropertyInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass)); + } + + [Test] + public void WhenAskProtectedPropertyThenFindIt() + { + var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName("ProtectedProperty"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("ProtectedProperty"); + memberInfo.Should().Be.InstanceOf<PropertyInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass)); + } + + [Test] + public void WhenAskMethodThenNull() + { + typeof(MyClass).GetPropertyOrFieldMatchingName("Method").Should().Be.Null(); + } + + [Test] + public void WhenAskPrivateFieldOnInheritedThenFindItOnInherited() + { + var memberInfo = typeof(Inherited).GetPropertyOrFieldMatchingName("pField"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("pField"); + memberInfo.DeclaringType.Should().Be(typeof(Inherited)); + memberInfo.ReflectedType.Should().Be(typeof(Inherited)); + memberInfo.Should().Be.InstanceOf<FieldInfo>(); + } + + [Test] + public void WhenAskPrivatePropertyOnInheritedThenFindItOnInherited() + { + var memberInfo = typeof(Inherited).GetPropertyOrFieldMatchingName("PrivateProperty"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("PrivateProperty"); + memberInfo.DeclaringType.Should().Be(typeof(Inherited)); + memberInfo.ReflectedType.Should().Be(typeof(Inherited)); + memberInfo.Should().Be.InstanceOf<PropertyInfo>(); + } + + [Test] + public void WhenAskPrivatePropertyOfBaseOnInheritedThenFindItOnBase() + { + var memberInfo = typeof(Inherited).GetPropertyOrFieldMatchingName("AnotherPrivateProperty"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("AnotherPrivateProperty"); + memberInfo.DeclaringType.Should().Be(typeof(MyClass)); + memberInfo.ReflectedType.Should().Be(typeof(MyClass)); + memberInfo.Should().Be.InstanceOf<PropertyInfo>(); + } + + [Test] + public void WhenAskPropertyOfInterfaceThenFindIt() + { + var memberInfo = typeof(IInterface).GetPropertyOrFieldMatchingName("Something"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("Something"); + memberInfo.DeclaringType.Should().Be(typeof(IInterface)); + memberInfo.ReflectedType.Should().Be(typeof(IInterface)); + memberInfo.Should().Be.InstanceOf<PropertyInfo>(); + } + + [Test] + public void WhenAskPropertyOfExplicitInterfaceThenFindItOnInterface() + { + var memberInfo = typeof(MyClassWithExplicitImpl).GetPropertyOrFieldMatchingName("Something"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("Something"); + memberInfo.DeclaringType.Should().Be(typeof(IInterface)); + memberInfo.ReflectedType.Should().Be(typeof(IInterface)); + memberInfo.Should().Be.InstanceOf<PropertyInfo>(); + } + + [Test] + public void WhenAskPropertyOfImplementedInterfaceThenFindItOnType() + { + var memberInfo = typeof(MyClassWithExplicitImpl).GetPropertyOrFieldMatchingName("SomethingElse"); + memberInfo.Should().Not.Be.Null(); + memberInfo.Name.Should().Be("SomethingElse"); + memberInfo.DeclaringType.Should().Be(typeof(MyClassWithExplicitImpl)); + memberInfo.ReflectedType.Should().Be(typeof(MyClassWithExplicitImpl)); + memberInfo.Should().Be.InstanceOf<PropertyInfo>(); + } + } +} \ 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 12:43:58 UTC (rev 5785) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-28 18:47:30 UTC (rev 5786) @@ -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\GetPropertyOrFieldMatchingNameTest.cs" /> <Compile Include="MappingByCode\TypeExtensionsTests\TypeExtensionsTest.cs" /> <Compile Include="MappingByCode\TypeNameUtilTests.cs" /> <Compile Include="NHSpecificTest\AccessAndCorrectPropertyName\Fixture.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |