Browse Source

added IdPropertyConvention

pull/11/head
craiggwilson 15 years ago
parent
commit
16494cf79e
  1. 1
      Bson/Bson.csproj
  2. 19
      Bson/DefaultSerializer/BsonClassMap.cs
  3. 32
      Bson/DefaultSerializer/Conventions/ConventionProfile.cs
  4. 28
      Bson/DefaultSerializer/Conventions/IdPropertyConventions.cs
  5. 1
      BsonUnitTests/BsonUnitTests.csproj
  6. 2
      BsonUnitTests/DefaultSerializer/BsonClassMapTests.cs
  7. 54
      BsonUnitTests/DefaultSerializer/Conventions/IdPropertyConventionsTests.cs

1
Bson/Bson.csproj

@ -76,6 +76,7 @@
<Compile Include="DefaultSerializer\BsonIdGenerators.cs" />
<Compile Include="DefaultSerializer\Conventions\ConventionProfile.cs" />
<Compile Include="DefaultSerializer\Conventions\ElementNameConventions.cs" />
<Compile Include="DefaultSerializer\Conventions\IdPropertyConventions.cs" />
<Compile Include="Exceptions\BsonInternalException.cs" />
<Compile Include="Exceptions\BsonSerializationException.cs" />
<Compile Include="ObjectModel\IConvertibleToBsonDocument.cs" />

19
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);
}
}

32
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<Type, bool> 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<Type, bool> 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;
}
}
}

28
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<BsonPropertyMap> propertyMaps);
}
public class NamedIdPropertyConvention : IIdPropertyConvention {
public string Name { get; private set; }
public NamedIdPropertyConvention(
string name
) {
Name = name;
}
public BsonPropertyMap FindIdPropertyMap(
IEnumerable<BsonPropertyMap> propertyMaps
) {
return propertyMaps.FirstOrDefault(x => x.PropertyName == Name);
}
}
}

1
BsonUnitTests/BsonUnitTests.csproj

@ -74,6 +74,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DefaultSerializer\BsonClassMapTests.cs" />
<Compile Include="DefaultSerializer\Conventions\IdPropertyConventionsTests.cs" />
<Compile Include="DefaultSerializer\Conventions\ElementNameConventionsTests.cs" />
<Compile Include="DefaultSerializer\SerializeFlagsTests.cs" />
<Compile Include="IO\BsonBufferValueStraddlesChunksTests.cs" />

2
BsonUnitTests/DefaultSerializer/BsonClassMapTests.cs

@ -37,7 +37,7 @@ namespace MongoDB.BsonUnitTests.DefaultSerializer {
}
[Test]
public void TestInt16UseCompactRepresentation() {
public void TestInt16UseCompactRepresentation() {
var classMap = BsonClassMap.RegisterClassMap<C>();
var sdPropertyMap = classMap.GetPropertyMap("SD");
var sfPropertyMap = classMap.GetPropertyMap("SF");

54
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<TestClassA>();
var idMap = convention.FindIdPropertyMap(classAMap.PropertyMaps);
Assert.IsNotNull(idMap);
Assert.AreEqual("Id", idMap.PropertyName);
var classBMap = BsonClassMap.RegisterClassMap<TestClassB>();
idMap = convention.FindIdPropertyMap(classBMap.PropertyMaps);
Assert.IsNull(idMap);
}
}
}
Loading…
Cancel
Save