diff --git a/Bson/Bson.csproj b/Bson/Bson.csproj
index f1599b30b4..a02fd1d3d8 100644
--- a/Bson/Bson.csproj
+++ b/Bson/Bson.csproj
@@ -76,6 +76,7 @@
+
diff --git a/Bson/DefaultSerializer/BsonClassMap.cs b/Bson/DefaultSerializer/BsonClassMap.cs
index 285c437dd5..d693c6fd3c 100644
--- a/Bson/DefaultSerializer/BsonClassMap.cs
+++ b/Bson/DefaultSerializer/BsonClassMap.cs
@@ -38,7 +38,8 @@ namespace MongoDB.Bson.DefaultSerializer {
#region protected fields
protected bool baseClassMapLoaded; // lazy load baseClassMap so class maps can be constructed out of order
protected BsonClassMap baseClassMap; // null for class object and interfaces
- protected Type classType;
+ protected Type classType;
+ protected ConventionProfile conventions;
protected string discriminator;
protected bool discriminatorIsRequired;
protected bool isAnonymous;
@@ -53,7 +54,8 @@ namespace MongoDB.Bson.DefaultSerializer {
protected BsonClassMap(
Type classType
) {
- this.classType = classType;
+ this.classType = classType;
+ this.conventions = GetConventionProfile(this.classType);
this.discriminator = classType.Name;
this.isAnonymous = IsAnonymousType(classType);
}
@@ -271,8 +273,6 @@ namespace MongoDB.Bson.DefaultSerializer {
BsonClassMap.LookupClassMap(knownTypeAttribute.KnownType); // will AutoMap KnownType if necessary
}
- var conventions = GetConventionProfile(classType);
-
var discriminatorAttribute = (BsonDiscriminatorAttribute) classType.GetCustomAttributes(typeof(BsonDiscriminatorAttribute), false).FirstOrDefault();
if (discriminatorAttribute != null) {
discriminator = discriminatorAttribute.Discriminator;
@@ -453,16 +453,7 @@ namespace MongoDB.Bson.DefaultSerializer {
// if no base class provided an idPropertyMap maybe we have one?
if (idPropertyMap == null) {
- // TODO: improve Id detection algorithm (doesn't have to be perfect since BsonIdAttribute can always pinpoint the Id property)
- // simple algorithm: first property found that ends in either "Id" or "id" or is of type ObjectId or Guid
- idPropertyMap = propertyMaps
- .Where(pm =>
- pm.PropertyName.EndsWith("Id") ||
- pm.PropertyName.EndsWith("id") ||
- pm.PropertyType == typeof(ObjectId) ||
- pm.PropertyType == typeof(Guid)
- )
- .FirstOrDefault();
+ idPropertyMap = conventions.IdPropertyConvention.FindIdPropertyMap(propertyMaps);
}
}
diff --git a/Bson/DefaultSerializer/Conventions/ConventionProfile.cs b/Bson/DefaultSerializer/Conventions/ConventionProfile.cs
index 28e5abde8c..c026e1bd25 100644
--- a/Bson/DefaultSerializer/Conventions/ConventionProfile.cs
+++ b/Bson/DefaultSerializer/Conventions/ConventionProfile.cs
@@ -6,20 +6,38 @@ using System.Text;
namespace MongoDB.Bson.DefaultSerializer.Conventions
{
public sealed class ConventionProfile {
- public static ConventionProfile Default { get; set; }
+ public static ConventionProfile Default { get; private set; }
public IElementNameConvention ElementNameConvention { get; private set; }
- static ConventionProfile()
- {
- Default = new ConventionProfile()
- .SetElementNameConvention(new MemberNameElementNameConvention());
+ public IIdPropertyConvention IdPropertyConvention { get; private set; }
+
+ public Func TypeFilter { get; private set; }
+
+ static ConventionProfile() {
+ Default = new ConventionProfile(t => true) //The default profile always matches...
+ .SetElementNameConvention(new MemberNameElementNameConvention())
+ .SetIdPropertyConvention(new NamedIdPropertyConvention("Id"));
+ }
+
+ public ConventionProfile(
+ Func typeFilter
+ ) {
+ TypeFilter = typeFilter;
}
- public ConventionProfile SetElementNameConvention(IElementNameConvention convention)
- {
+ public ConventionProfile SetElementNameConvention(
+ IElementNameConvention convention
+ ) {
ElementNameConvention = convention;
return this;
}
+
+ public ConventionProfile SetIdPropertyConvention(
+ IIdPropertyConvention convention
+ ) {
+ IdPropertyConvention = convention;
+ return this;
+ }
}
}
\ No newline at end of file
diff --git a/Bson/DefaultSerializer/Conventions/IdPropertyConventions.cs b/Bson/DefaultSerializer/Conventions/IdPropertyConventions.cs
new file mode 100644
index 0000000000..9eedf5033f
--- /dev/null
+++ b/Bson/DefaultSerializer/Conventions/IdPropertyConventions.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+
+namespace MongoDB.Bson.DefaultSerializer.Conventions
+{
+ public interface IIdPropertyConvention {
+ BsonPropertyMap FindIdPropertyMap(IEnumerable propertyMaps);
+ }
+
+ public class NamedIdPropertyConvention : IIdPropertyConvention {
+ public string Name { get; private set; }
+
+ public NamedIdPropertyConvention(
+ string name
+ ) {
+ Name = name;
+ }
+
+ public BsonPropertyMap FindIdPropertyMap(
+ IEnumerable propertyMaps
+ ) {
+ return propertyMaps.FirstOrDefault(x => x.PropertyName == Name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BsonUnitTests/BsonUnitTests.csproj b/BsonUnitTests/BsonUnitTests.csproj
index a762cb7e54..fd7551abd1 100644
--- a/BsonUnitTests/BsonUnitTests.csproj
+++ b/BsonUnitTests/BsonUnitTests.csproj
@@ -74,6 +74,7 @@
+
diff --git a/BsonUnitTests/DefaultSerializer/BsonClassMapTests.cs b/BsonUnitTests/DefaultSerializer/BsonClassMapTests.cs
index 8a45aa728d..a93959ed2c 100644
--- a/BsonUnitTests/DefaultSerializer/BsonClassMapTests.cs
+++ b/BsonUnitTests/DefaultSerializer/BsonClassMapTests.cs
@@ -37,7 +37,7 @@ namespace MongoDB.BsonUnitTests.DefaultSerializer {
}
[Test]
- public void TestInt16UseCompactRepresentation() {
+ public void TestInt16UseCompactRepresentation() {
var classMap = BsonClassMap.RegisterClassMap();
var sdPropertyMap = classMap.GetPropertyMap("SD");
var sfPropertyMap = classMap.GetPropertyMap("SF");
diff --git a/BsonUnitTests/DefaultSerializer/Conventions/IdPropertyConventionsTests.cs b/BsonUnitTests/DefaultSerializer/Conventions/IdPropertyConventionsTests.cs
new file mode 100644
index 0000000000..3a67eda1ea
--- /dev/null
+++ b/BsonUnitTests/DefaultSerializer/Conventions/IdPropertyConventionsTests.cs
@@ -0,0 +1,54 @@
+/* Copyright 2010 10gen Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+using MongoDB.Bson.DefaultSerializer.Conventions;
+using MongoDB.Bson;
+using MongoDB.Bson.DefaultSerializer;
+
+namespace MongoDB.BsonUnitTests.DefaultSerializer.Conventions
+{
+ [TestFixture]
+ public class IdPropertyConventionsTests {
+ private class TestClassA {
+ public Guid Id { get; set; }
+ public ObjectId OtherId { get; set; }
+ }
+
+ private class TestClassB {
+ public ObjectId OtherId { get; set; }
+ }
+
+ [Test]
+ public void TestIdPropertyConvention() {
+ var convention = new NamedIdPropertyConvention("Id");
+
+ var classAMap = BsonClassMap.RegisterClassMap();
+ var idMap = convention.FindIdPropertyMap(classAMap.PropertyMaps);
+ Assert.IsNotNull(idMap);
+ Assert.AreEqual("Id", idMap.PropertyName);
+
+ var classBMap = BsonClassMap.RegisterClassMap();
+ idMap = convention.FindIdPropertyMap(classBMap.PropertyMaps);
+ Assert.IsNull(idMap);
+ }
+ }
+}