Browse files

CSHARP-708: fixed bug where interface maps were too strict with regar…

…ds to mapping a member back to it's interface declaration.
  • Loading branch information...
1 parent 9c96999 commit 97bb29236f5fc11f7b60de653012e2721e8c23a9 @craiggwilson craiggwilson committed Mar 20, 2013
Showing with 21 additions and 34 deletions.
  1. +12 −25 MongoDB.Bson/Serialization/BsonClassMap.cs
  2. +9 −9 MongoDB.BsonUnitTests/Jira/CSharp708Tests.cs
View
37 MongoDB.Bson/Serialization/BsonClassMap.cs
@@ -1566,7 +1566,7 @@ private static MemberInfo GetMemberInfoFromLambda<TMember>(Expression<Func<TClas
case MemberTypes.Property:
if (memberInfo.DeclaringType.IsInterface)
{
- memberInfo = ResolveExplicitProperty(memberInfo, typeof(TClass));
+ memberInfo = FindPropertyImplementation((PropertyInfo)memberInfo, typeof(TClass));
}
break;
default:
@@ -1585,45 +1585,32 @@ private static string GetMemberNameFromLambda<TMember>(Expression<Func<TClass, T
return GetMemberInfoFromLambda(memberLambda).Name;
}
- private static PropertyInfo ResolveExplicitProperty(MemberInfo interfaceMemberInfo, Type targetType)
+ private static PropertyInfo FindPropertyImplementation(PropertyInfo interfacePropertyInfo, Type actualType)
{
- var interfaceType = interfaceMemberInfo.DeclaringType;
+ var interfaceType = interfacePropertyInfo.DeclaringType;
// An interface map must be used because because there is no
// other officially documented way to derive the explicitly
// implemented property name.
- var interfaceMap = targetType.GetInterfaceMap(interfaceType);
+ var interfaceMap = actualType.GetInterfaceMap(interfaceType);
- var interfacePropertyAccessors = ((PropertyInfo)interfaceMemberInfo).GetAccessors(true);
+ var interfacePropertyAccessors = interfacePropertyInfo.GetAccessors(true);
- var targetPropertyAccessors = interfacePropertyAccessors.Select(accessor =>
+ var actualPropertyAccessors = interfacePropertyAccessors.Select(interfacePropertyAccessor =>
{
- var index = Array.IndexOf<MethodInfo>(interfaceMap.InterfaceMethods, accessor);
+ var index = Array.IndexOf<MethodInfo>(interfaceMap.InterfaceMethods, interfacePropertyAccessor);
return interfaceMap.TargetMethods[index];
- }).ToArray();
+ });
// Binding must be done by accessor methods because interface
// maps only map accessor methods and do not map properties.
- return targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
+ return actualType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Single(propertyInfo =>
{
- var accessors = propertyInfo.GetAccessors(true);
-
- if (accessors.Length != targetPropertyAccessors.Length)
- {
- return false;
- }
-
- for (var i = 0; i < accessors.Length; ++i)
- {
- if(!targetPropertyAccessors.Contains(accessors[i]))
- {
- return false;
- }
- }
-
- return true;
+ // we are looking for a property that implements all the required accessors
+ var propertyAccessors = propertyInfo.GetAccessors(true);
+ return actualPropertyAccessors.All(x => propertyAccessors.Contains(x));
});
}
}
View
18 MongoDB.BsonUnitTests/Jira/CSharp708Tests.cs
@@ -1,4 +1,4 @@
-/* Copyright 2010-2012 10gen Inc.
+/* Copyright 2010-2013 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,11 +13,8 @@
* limitations under the License.
*/
-using MongoDB.Bson;
-using MongoDB.Bson.Serialization.Attributes;
-using NUnit.Framework;
using MongoDB.Bson.Serialization;
-using MongoDB.Bson.Serialization.Conventions;
+using NUnit.Framework;
namespace MongoDB.BsonUnitTests.Jira.CSharp708
{
@@ -34,19 +31,22 @@ class Entity : IIdentity
public string Id { get; set; }
}
- void ConfigureClassMap<T>(BsonClassMap<T> cm)
+ BsonMemberMap GetIdMemberMap<T>(BsonClassMap<T> cm)
where T : class, IIdentity, new()
{
- cm.SetIdMember(cm.GetMemberMap(c => c.Id).SetRepresentation(BsonType.ObjectId));
+ return cm.GetMemberMap(x => x.Id);
}
[Test]
- public void Test()
+ public void TestGetMemberFindsCorrectMember()
{
var classMap = new BsonClassMap<Entity>();
classMap.AutoMap();
- ConfigureClassMap<Entity>(classMap);
+ var memberMap = GetIdMemberMap<Entity>(classMap);
+
+ Assert.IsNotNull(memberMap);
+ Assert.AreEqual("Id", memberMap.MemberName);
}
}
}

0 comments on commit 97bb292

Please sign in to comment.