Skip to content

Commit 97bb292

Browse files
committed
CSHARP-708: fixed bug where interface maps were too strict with regards to mapping a member back to it's interface declaration.
1 parent 9c96999 commit 97bb292

File tree

2 files changed

+21
-34
lines changed

2 files changed

+21
-34
lines changed

MongoDB.Bson/Serialization/BsonClassMap.cs

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,7 +1566,7 @@ private static MemberInfo GetMemberInfoFromLambda<TMember>(Expression<Func<TClas
15661566
case MemberTypes.Property:
15671567
if (memberInfo.DeclaringType.IsInterface)
15681568
{
1569-
memberInfo = ResolveExplicitProperty(memberInfo, typeof(TClass));
1569+
memberInfo = FindPropertyImplementation((PropertyInfo)memberInfo, typeof(TClass));
15701570
}
15711571
break;
15721572
default:
@@ -1585,45 +1585,32 @@ private static string GetMemberNameFromLambda<TMember>(Expression<Func<TClass, T
15851585
return GetMemberInfoFromLambda(memberLambda).Name;
15861586
}
15871587

1588-
private static PropertyInfo ResolveExplicitProperty(MemberInfo interfaceMemberInfo, Type targetType)
1588+
private static PropertyInfo FindPropertyImplementation(PropertyInfo interfacePropertyInfo, Type actualType)
15891589
{
1590-
var interfaceType = interfaceMemberInfo.DeclaringType;
1590+
var interfaceType = interfacePropertyInfo.DeclaringType;
15911591

15921592
// An interface map must be used because because there is no
15931593
// other officially documented way to derive the explicitly
15941594
// implemented property name.
1595-
var interfaceMap = targetType.GetInterfaceMap(interfaceType);
1595+
var interfaceMap = actualType.GetInterfaceMap(interfaceType);
15961596

1597-
var interfacePropertyAccessors = ((PropertyInfo)interfaceMemberInfo).GetAccessors(true);
1597+
var interfacePropertyAccessors = interfacePropertyInfo.GetAccessors(true);
15981598

1599-
var targetPropertyAccessors = interfacePropertyAccessors.Select(accessor =>
1599+
var actualPropertyAccessors = interfacePropertyAccessors.Select(interfacePropertyAccessor =>
16001600
{
1601-
var index = Array.IndexOf<MethodInfo>(interfaceMap.InterfaceMethods, accessor);
1601+
var index = Array.IndexOf<MethodInfo>(interfaceMap.InterfaceMethods, interfacePropertyAccessor);
16021602

16031603
return interfaceMap.TargetMethods[index];
1604-
}).ToArray();
1604+
});
16051605

16061606
// Binding must be done by accessor methods because interface
16071607
// maps only map accessor methods and do not map properties.
1608-
return targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
1608+
return actualType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
16091609
.Single(propertyInfo =>
16101610
{
1611-
var accessors = propertyInfo.GetAccessors(true);
1612-
1613-
if (accessors.Length != targetPropertyAccessors.Length)
1614-
{
1615-
return false;
1616-
}
1617-
1618-
for (var i = 0; i < accessors.Length; ++i)
1619-
{
1620-
if(!targetPropertyAccessors.Contains(accessors[i]))
1621-
{
1622-
return false;
1623-
}
1624-
}
1625-
1626-
return true;
1611+
// we are looking for a property that implements all the required accessors
1612+
var propertyAccessors = propertyInfo.GetAccessors(true);
1613+
return actualPropertyAccessors.All(x => propertyAccessors.Contains(x));
16271614
});
16281615
}
16291616
}

MongoDB.BsonUnitTests/Jira/CSharp708Tests.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2010-2012 10gen Inc.
1+
/* Copyright 2010-2013 10gen Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -13,11 +13,8 @@
1313
* limitations under the License.
1414
*/
1515

16-
using MongoDB.Bson;
17-
using MongoDB.Bson.Serialization.Attributes;
18-
using NUnit.Framework;
1916
using MongoDB.Bson.Serialization;
20-
using MongoDB.Bson.Serialization.Conventions;
17+
using NUnit.Framework;
2118

2219
namespace MongoDB.BsonUnitTests.Jira.CSharp708
2320
{
@@ -34,19 +31,22 @@ class Entity : IIdentity
3431
public string Id { get; set; }
3532
}
3633

37-
void ConfigureClassMap<T>(BsonClassMap<T> cm)
34+
BsonMemberMap GetIdMemberMap<T>(BsonClassMap<T> cm)
3835
where T : class, IIdentity, new()
3936
{
40-
cm.SetIdMember(cm.GetMemberMap(c => c.Id).SetRepresentation(BsonType.ObjectId));
37+
return cm.GetMemberMap(x => x.Id);
4138
}
4239

4340
[Test]
44-
public void Test()
41+
public void TestGetMemberFindsCorrectMember()
4542
{
4643
var classMap = new BsonClassMap<Entity>();
4744
classMap.AutoMap();
4845

49-
ConfigureClassMap<Entity>(classMap);
46+
var memberMap = GetIdMemberMap<Entity>(classMap);
47+
48+
Assert.IsNotNull(memberMap);
49+
Assert.AreEqual("Id", memberMap.MemberName);
5050
}
5151
}
5252
}

0 commit comments

Comments
 (0)