Skip to content

Commit 26934fd

Browse files
committed
by-code: Preparing to add new API for private/protected properties/fields
SVN: trunk@5786
1 parent e5cf3d0 commit 26934fd

File tree

3 files changed

+268
-3
lines changed

3 files changed

+268
-3
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
using System;
2+
using System.Reflection;
3+
using NHibernate.Mapping.ByCode;
4+
using NUnit.Framework;
5+
using SharpTestsEx;
6+
namespace NHibernate.Test.MappingByCode.TypeExtensionsTests
7+
{
8+
public class GetPropertyOrFieldMatchingNameTest
9+
{
10+
private class MyClass
11+
{
12+
private int pField;
13+
private int PrivateProperty { get; set; }
14+
private int AnotherPrivateProperty { get; set; }
15+
protected int ProtectedProperty { get; set; }
16+
private int Method() { return 0; }
17+
}
18+
19+
private class Inherited: MyClass
20+
{
21+
private int pField;
22+
private int PrivateProperty { get; set; }
23+
}
24+
25+
private interface IInterface
26+
{
27+
int Something { get; set; }
28+
int SomethingElse { get; set; }
29+
}
30+
31+
private class MyClassWithExplicitImpl: IInterface
32+
{
33+
int IInterface.Something
34+
{
35+
get
36+
{
37+
throw new System.NotImplementedException();
38+
}
39+
set
40+
{
41+
throw new System.NotImplementedException();
42+
}
43+
}
44+
45+
public int SomethingElse
46+
{
47+
get { throw new NotImplementedException(); }
48+
set { throw new NotImplementedException(); }
49+
}
50+
}
51+
52+
[Test]
53+
public void WhenNullTypeThenThrows()
54+
{
55+
Executing.This(() => ((System.Type)null).GetPropertyOrFieldMatchingName("A")).Should().Throw<ArgumentNullException>();
56+
}
57+
58+
[Test]
59+
public void WhenAskNullThenNull()
60+
{
61+
typeof(MyClass).GetPropertyOrFieldMatchingName(null).Should().Be.Null();
62+
}
63+
64+
[Test]
65+
public void WhenAskNotExistentThenNull()
66+
{
67+
typeof(MyClass).GetPropertyOrFieldMatchingName("NotExistent").Should().Be.Null();
68+
}
69+
70+
[Test]
71+
public void WhenAskPrivateFieldThenFindIt()
72+
{
73+
var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName("pField");
74+
memberInfo.Should().Not.Be.Null();
75+
memberInfo.Name.Should().Be("pField");
76+
memberInfo.Should().Be.InstanceOf<FieldInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass));
77+
}
78+
79+
[Test]
80+
public void WhenAskPrivateFieldWithBlanksThenFindIt()
81+
{
82+
var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName(" pField ");
83+
memberInfo.Should().Not.Be.Null();
84+
memberInfo.Name.Should().Be("pField");
85+
memberInfo.Should().Be.InstanceOf<FieldInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass));
86+
}
87+
88+
[Test]
89+
public void WhenAskPrivatePropertyThenFindIt()
90+
{
91+
var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName("PrivateProperty");
92+
memberInfo.Should().Not.Be.Null();
93+
memberInfo.Name.Should().Be("PrivateProperty");
94+
memberInfo.Should().Be.InstanceOf<PropertyInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass));
95+
}
96+
97+
[Test]
98+
public void WhenAskProtectedPropertyThenFindIt()
99+
{
100+
var memberInfo = typeof(MyClass).GetPropertyOrFieldMatchingName("ProtectedProperty");
101+
memberInfo.Should().Not.Be.Null();
102+
memberInfo.Name.Should().Be("ProtectedProperty");
103+
memberInfo.Should().Be.InstanceOf<PropertyInfo>().And.ValueOf.DeclaringType.Should().Be(typeof(MyClass));
104+
}
105+
106+
[Test]
107+
public void WhenAskMethodThenNull()
108+
{
109+
typeof(MyClass).GetPropertyOrFieldMatchingName("Method").Should().Be.Null();
110+
}
111+
112+
[Test]
113+
public void WhenAskPrivateFieldOnInheritedThenFindItOnInherited()
114+
{
115+
var memberInfo = typeof(Inherited).GetPropertyOrFieldMatchingName("pField");
116+
memberInfo.Should().Not.Be.Null();
117+
memberInfo.Name.Should().Be("pField");
118+
memberInfo.DeclaringType.Should().Be(typeof(Inherited));
119+
memberInfo.ReflectedType.Should().Be(typeof(Inherited));
120+
memberInfo.Should().Be.InstanceOf<FieldInfo>();
121+
}
122+
123+
[Test]
124+
public void WhenAskPrivatePropertyOnInheritedThenFindItOnInherited()
125+
{
126+
var memberInfo = typeof(Inherited).GetPropertyOrFieldMatchingName("PrivateProperty");
127+
memberInfo.Should().Not.Be.Null();
128+
memberInfo.Name.Should().Be("PrivateProperty");
129+
memberInfo.DeclaringType.Should().Be(typeof(Inherited));
130+
memberInfo.ReflectedType.Should().Be(typeof(Inherited));
131+
memberInfo.Should().Be.InstanceOf<PropertyInfo>();
132+
}
133+
134+
[Test]
135+
public void WhenAskPrivatePropertyOfBaseOnInheritedThenFindItOnBase()
136+
{
137+
var memberInfo = typeof(Inherited).GetPropertyOrFieldMatchingName("AnotherPrivateProperty");
138+
memberInfo.Should().Not.Be.Null();
139+
memberInfo.Name.Should().Be("AnotherPrivateProperty");
140+
memberInfo.DeclaringType.Should().Be(typeof(MyClass));
141+
memberInfo.ReflectedType.Should().Be(typeof(MyClass));
142+
memberInfo.Should().Be.InstanceOf<PropertyInfo>();
143+
}
144+
145+
[Test]
146+
public void WhenAskPropertyOfInterfaceThenFindIt()
147+
{
148+
var memberInfo = typeof(IInterface).GetPropertyOrFieldMatchingName("Something");
149+
memberInfo.Should().Not.Be.Null();
150+
memberInfo.Name.Should().Be("Something");
151+
memberInfo.DeclaringType.Should().Be(typeof(IInterface));
152+
memberInfo.ReflectedType.Should().Be(typeof(IInterface));
153+
memberInfo.Should().Be.InstanceOf<PropertyInfo>();
154+
}
155+
156+
[Test]
157+
public void WhenAskPropertyOfExplicitInterfaceThenFindItOnInterface()
158+
{
159+
var memberInfo = typeof(MyClassWithExplicitImpl).GetPropertyOrFieldMatchingName("Something");
160+
memberInfo.Should().Not.Be.Null();
161+
memberInfo.Name.Should().Be("Something");
162+
memberInfo.DeclaringType.Should().Be(typeof(IInterface));
163+
memberInfo.ReflectedType.Should().Be(typeof(IInterface));
164+
memberInfo.Should().Be.InstanceOf<PropertyInfo>();
165+
}
166+
167+
[Test]
168+
public void WhenAskPropertyOfImplementedInterfaceThenFindItOnType()
169+
{
170+
var memberInfo = typeof(MyClassWithExplicitImpl).GetPropertyOrFieldMatchingName("SomethingElse");
171+
memberInfo.Should().Not.Be.Null();
172+
memberInfo.Name.Should().Be("SomethingElse");
173+
memberInfo.DeclaringType.Should().Be(typeof(MyClassWithExplicitImpl));
174+
memberInfo.ReflectedType.Should().Be(typeof(MyClassWithExplicitImpl));
175+
memberInfo.Should().Be.InstanceOf<PropertyInfo>();
176+
}
177+
}
178+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@
612612
<Compile Include="MappingByCode\TypeExtensionsTests\GetFirstImplementorConcreteClassesTest.cs" />
613613
<Compile Include="MappingByCode\TypeExtensionsTests\GetFirstImplementorTest.cs" />
614614
<Compile Include="MappingByCode\TypeExtensionsTests\GetMemberFromInterfacesTest.cs" />
615+
<Compile Include="MappingByCode\TypeExtensionsTests\GetPropertyOrFieldMatchingNameTest.cs" />
615616
<Compile Include="MappingByCode\TypeExtensionsTests\TypeExtensionsTest.cs" />
616617
<Compile Include="MappingByCode\TypeNameUtilTests.cs" />
617618
<Compile Include="NHSpecificTest\AccessAndCorrectPropertyName\Fixture.cs" />

src/NHibernate/Mapping/ByCode/TypeExtensions.cs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ namespace NHibernate.Mapping.ByCode
99
{
1010
public static class TypeExtensions
1111
{
12-
private const BindingFlags PublicPropertiesOfClassHierarchy =
12+
private const BindingFlags PropertiesOfClassHierarchy =
1313
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
14+
private const BindingFlags PropertiesOrFieldOfClass = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
1415

1516
public static IEnumerable<System.Type> GetBaseTypes(this System.Type type)
1617
{
@@ -410,12 +411,97 @@ public static System.Type GetFirstImplementorOf(this System.Type source, System.
410411

411412
public static bool HasPublicPropertyOf(this System.Type source, System.Type typeOfProperty)
412413
{
413-
return GetFirstPropertyOfType(source, typeOfProperty, PublicPropertiesOfClassHierarchy) != null;
414+
return GetFirstPropertyOfType(source, typeOfProperty, PropertiesOfClassHierarchy) != null;
414415
}
415416

416417
public static bool HasPublicPropertyOf(this System.Type source, System.Type typeOfProperty, Func<PropertyInfo, bool> acceptPropertyClauses)
417418
{
418-
return GetFirstPropertyOfType(source, typeOfProperty, PublicPropertiesOfClassHierarchy, acceptPropertyClauses) != null;
419+
return GetFirstPropertyOfType(source, typeOfProperty, PropertiesOfClassHierarchy, acceptPropertyClauses) != null;
420+
}
421+
422+
/// <summary>
423+
/// Try to find a property or field from a given type.
424+
/// </summary>
425+
/// <param name="source">The type</param>
426+
/// <param name="memberName">The property or field name.</param>
427+
/// <returns>
428+
/// A <see cref="PropertyInfo"/> or a <see cref="FieldInfo"/> where the member is found; null otherwise.
429+
/// </returns>
430+
/// <remarks>
431+
/// Where found the member is returned always from the declaring type.
432+
/// </remarks>
433+
public static MemberInfo GetPropertyOrFieldMatchingName(this System.Type source, string memberName)
434+
{
435+
if (source == null)
436+
{
437+
throw new ArgumentNullException("source");
438+
}
439+
if (memberName == null)
440+
{
441+
return null;
442+
}
443+
var nameToFind = memberName.Trim();
444+
var members = source.GetPropertiesOfHierarchy().Concat(source.GetFieldsOfHierarchy()).Concat(source.GetPropertiesOfInterfacesImplemented());
445+
return members.FirstOrDefault(x => x.Name == nameToFind);
446+
}
447+
448+
private static IEnumerable<MemberInfo> GetPropertiesOfInterfacesImplemented(this System.Type source)
449+
{
450+
if (source.IsInterface)
451+
{
452+
foreach (var interfaceProperty in source.GetInterfaceProperties())
453+
{
454+
yield return interfaceProperty;
455+
}
456+
yield break;
457+
}
458+
foreach (var @interface in source.GetInterfaces())
459+
{
460+
foreach (var interfaceProperty in @interface.GetInterfaceProperties())
461+
{
462+
yield return interfaceProperty;
463+
}
464+
}
465+
}
466+
467+
private static IEnumerable<MemberInfo> GetPropertiesOfHierarchy(this System.Type type)
468+
{
469+
if(type.IsInterface)
470+
{
471+
yield break;
472+
}
473+
System.Type analizing = type;
474+
while (analizing != null && analizing != typeof(object))
475+
{
476+
foreach (PropertyInfo propertyInfo in analizing.GetProperties(PropertiesOrFieldOfClass))
477+
{
478+
yield return propertyInfo;
479+
}
480+
analizing = analizing.BaseType;
481+
}
482+
}
483+
484+
private static IEnumerable<MemberInfo> GetFieldsOfHierarchy(this System.Type type)
485+
{
486+
if (type.IsInterface)
487+
{
488+
yield break;
489+
}
490+
System.Type analizing = type;
491+
while (analizing != null && analizing != typeof(object))
492+
{
493+
foreach (FieldInfo fieldInfo in GetUserDeclaredFields(analizing))
494+
{
495+
yield return fieldInfo;
496+
}
497+
analizing = analizing.BaseType;
498+
}
499+
}
500+
501+
private static IEnumerable<FieldInfo> GetUserDeclaredFields(System.Type type)
502+
{
503+
// can't find another way to exclude fields generated by the compiler (for both auto-properties and anonymous-types)
504+
return type.GetFields(PropertiesOrFieldOfClass).Where(x => !x.Name.StartsWith("<"));
419505
}
420506
}
421507
}

0 commit comments

Comments
 (0)