Skip to content

Commit 82be5e5

Browse files
committed
GetMemberFromReflectedType implemented
SVN: trunk@5787
1 parent 26934fd commit 82be5e5

File tree

3 files changed

+189
-0
lines changed

3 files changed

+189
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
using System;
2+
using System.Reflection;
3+
using NHibernate.Mapping.ByCode;
4+
using NUnit.Framework;
5+
using SharpTestsEx;
6+
7+
namespace NHibernate.Test.MappingByCode.TypeExtensionsTests
8+
{
9+
public class GetMemberFromReflectedTest
10+
{
11+
private const BindingFlags PrivateMembersFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
12+
13+
private class MyClass
14+
{
15+
private int pField;
16+
private int PrivateProperty { get; set; }
17+
public int AnotherProperty { get; set; }
18+
protected int ProtectedProperty { get; set; }
19+
private int Method() { return 0; }
20+
}
21+
22+
private class Inherited : MyClass
23+
{
24+
private int pField;
25+
private int PrivateProperty { get; set; }
26+
}
27+
28+
private interface IInterface
29+
{
30+
int Something { get; set; }
31+
int SomethingElse { get; set; }
32+
}
33+
34+
private class MyClassWithExplicitImpl : IInterface
35+
{
36+
int IInterface.Something
37+
{
38+
get
39+
{
40+
throw new System.NotImplementedException();
41+
}
42+
set
43+
{
44+
throw new System.NotImplementedException();
45+
}
46+
}
47+
48+
public int SomethingElse
49+
{
50+
get { throw new NotImplementedException(); }
51+
set { throw new NotImplementedException(); }
52+
}
53+
}
54+
55+
[Test]
56+
public void WhenNullMemberThenThrows()
57+
{
58+
Executing.This(() => ((MemberInfo)null).GetMemberFromReflectedType(typeof(MyClass))).Should().Throw<ArgumentNullException>();
59+
}
60+
61+
[Test]
62+
public void WhenNullTypeThenThrows()
63+
{
64+
Executing.This(() => typeof(MyClassWithExplicitImpl).GetProperty("SomethingElse").GetMemberFromReflectedType(null)).Should().Throw<ArgumentNullException>();
65+
}
66+
67+
[Test]
68+
public void WhenNotExistentThenOriginal()
69+
{
70+
var propertyInfo = typeof(MyClassWithExplicitImpl).GetProperty("SomethingElse");
71+
propertyInfo.GetMemberFromReflectedType(typeof(object)).Should().Be(propertyInfo);
72+
}
73+
74+
[Test]
75+
public void WhenNotAccessibleFieldThenOriginal()
76+
{
77+
var memberInfo = typeof(MyClass).GetField("pField", PrivateMembersFlags);
78+
memberInfo.GetMemberFromReflectedType(typeof(Inherited)).Should().Be(memberInfo);
79+
}
80+
81+
[Test]
82+
public void WhenNotAccessiblePropertyThenOriginal()
83+
{
84+
var memberInfo = typeof(MyClass).GetProperty("PrivateProperty", PrivateMembersFlags);
85+
memberInfo.GetMemberFromReflectedType(typeof(Inherited)).Should().Be(memberInfo);
86+
}
87+
88+
[Test]
89+
public void WhenAccessiblePropertyThenReflected()
90+
{
91+
var memberInfo = typeof(MyClass).GetProperty("ProtectedProperty", PrivateMembersFlags);
92+
var result = memberInfo.GetMemberFromReflectedType(typeof(Inherited));
93+
result.ReflectedType.Should().Be(typeof(Inherited));
94+
result.DeclaringType.Should().Be(typeof(MyClass));
95+
}
96+
97+
[Test]
98+
public void WhenPrivateFieldOnInheritedThenFindItOnInherited()
99+
{
100+
var memberInfo = typeof(Inherited).GetField("pField", PrivateMembersFlags);
101+
var result = memberInfo.GetMemberFromReflectedType(typeof(MyClass));
102+
result.ReflectedType.Should().Be(typeof(Inherited));
103+
result.DeclaringType.Should().Be(typeof(Inherited));
104+
}
105+
106+
[Test]
107+
public void WhenPublicPropertyOfBaseOnInheritedThenFindItOnInherited()
108+
{
109+
var memberInfo = typeof(MyClass).GetProperty("AnotherProperty");
110+
var result = memberInfo.GetMemberFromReflectedType(typeof(Inherited));
111+
result.ReflectedType.Should().Be(typeof(Inherited));
112+
result.DeclaringType.Should().Be(typeof(MyClass));
113+
}
114+
115+
[Test]
116+
public void WhenPropertyOfInterfaceThenFindItOnClass()
117+
{
118+
var memberInfo = typeof(IInterface).GetProperty("SomethingElse");
119+
var result = memberInfo.GetMemberFromReflectedType(typeof(MyClassWithExplicitImpl));
120+
result.DeclaringType.Should().Be(typeof(MyClassWithExplicitImpl));
121+
result.ReflectedType.Should().Be(typeof(MyClassWithExplicitImpl));
122+
}
123+
124+
[Test]
125+
public void WhenPropertyOfExplicitInterfaceThenFindItOnClass()
126+
{
127+
var memberInfo = typeof(IInterface).GetProperty("Something");
128+
var result = memberInfo.GetMemberFromReflectedType(typeof(MyClassWithExplicitImpl));
129+
result.DeclaringType.Should().Be(typeof(MyClassWithExplicitImpl));
130+
result.ReflectedType.Should().Be(typeof(MyClassWithExplicitImpl));
131+
}
132+
}
133+
}

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\GetMemberFromReflectedTest.cs" />
615616
<Compile Include="MappingByCode\TypeExtensionsTests\GetPropertyOrFieldMatchingNameTest.cs" />
616617
<Compile Include="MappingByCode\TypeExtensionsTests\TypeExtensionsTest.cs" />
617618
<Compile Include="MappingByCode\TypeNameUtilTests.cs" />

src/NHibernate/Mapping/ByCode/TypeExtensions.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,61 @@ public static bool HasPublicPropertyOf(this System.Type source, System.Type type
419419
return GetFirstPropertyOfType(source, typeOfProperty, PropertiesOfClassHierarchy, acceptPropertyClauses) != null;
420420
}
421421

422+
/// <summary>
423+
/// Given a property or a field try to get the member from a given possible inherited type.
424+
/// </summary>
425+
/// <param name="member">The member to find.</param>
426+
/// <param name="reflectedType">The type where find the member.</param>
427+
/// <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>
428+
public static MemberInfo GetMemberFromReflectedType(this MemberInfo member, System.Type reflectedType)
429+
{
430+
if (member == null)
431+
{
432+
throw new ArgumentNullException("member");
433+
}
434+
if (reflectedType == null)
435+
{
436+
throw new ArgumentNullException("reflectedType");
437+
}
438+
var field = member as FieldInfo;
439+
if (field != null && field.IsPrivate)
440+
{
441+
return member;
442+
}
443+
var property = member as PropertyInfo;
444+
if (property != null)
445+
{
446+
var propertyGetter = property.GetGetMethod(true);
447+
if (propertyGetter.IsPrivate)
448+
{
449+
return member;
450+
}
451+
if (property.DeclaringType.IsInterface)
452+
{
453+
System.Type[] interfaces = reflectedType.GetInterfaces();
454+
var @interface = property.DeclaringType;
455+
if (!interfaces.Contains(@interface))
456+
{
457+
return member;
458+
}
459+
var reflectedCandidateProps = reflectedType.GetProperties(PropertiesOfClassHierarchy);
460+
InterfaceMapping memberMap = reflectedType.GetInterfaceMap(@interface);
461+
for (int i = 0; i < memberMap.TargetMethods.Length; i++)
462+
{
463+
if (memberMap.InterfaceMethods[i] == propertyGetter)
464+
{
465+
return reflectedCandidateProps.Single(pi => pi.GetGetMethod(true) == memberMap.TargetMethods[i]);
466+
}
467+
}
468+
return member;
469+
}
470+
}
471+
var reflectedTypeProperties = reflectedType.GetProperties(PropertiesOfClassHierarchy);
472+
var members = reflectedTypeProperties.Cast<MemberInfo>().Concat(reflectedType.GetFields(PropertiesOfClassHierarchy));
473+
var result = members.FirstOrDefault(m=> m.Name.Equals(member.Name) && m.GetPropertyOrFieldType().Equals(member.GetPropertyOrFieldType()));
474+
return result ?? member;
475+
}
476+
422477
/// <summary>
423478
/// Try to find a property or field from a given type.
424479
/// </summary>

0 commit comments

Comments
 (0)