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\BsonIdGenerators.cs" />
<Compile Include="DefaultSerializer\Conventions\ConventionProfile.cs" /> <Compile Include="DefaultSerializer\Conventions\ConventionProfile.cs" />
<Compile Include="DefaultSerializer\Conventions\ElementNameConventions.cs" /> <Compile Include="DefaultSerializer\Conventions\ElementNameConventions.cs" />
<Compile Include="DefaultSerializer\Conventions\IdPropertyConventions.cs" />
<Compile Include="Exceptions\BsonInternalException.cs" /> <Compile Include="Exceptions\BsonInternalException.cs" />
<Compile Include="Exceptions\BsonSerializationException.cs" /> <Compile Include="Exceptions\BsonSerializationException.cs" />
<Compile Include="ObjectModel\IConvertibleToBsonDocument.cs" /> <Compile Include="ObjectModel\IConvertibleToBsonDocument.cs" />

19
Bson/DefaultSerializer/BsonClassMap.cs

@ -38,7 +38,8 @@ namespace MongoDB.Bson.DefaultSerializer {
#region protected fields #region protected fields
protected bool baseClassMapLoaded; // lazy load baseClassMap so class maps can be constructed out of order 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 BsonClassMap baseClassMap; // null for class object and interfaces
protected Type classType;
protected Type classType;
protected ConventionProfile conventions;
protected string discriminator; protected string discriminator;
protected bool discriminatorIsRequired; protected bool discriminatorIsRequired;
protected bool isAnonymous; protected bool isAnonymous;
@ -53,7 +54,8 @@ namespace MongoDB.Bson.DefaultSerializer {
protected BsonClassMap( protected BsonClassMap(
Type classType Type classType
) { ) {
this.classType = classType;
this.classType = classType;
this.conventions = GetConventionProfile(this.classType);
this.discriminator = classType.Name; this.discriminator = classType.Name;
this.isAnonymous = IsAnonymousType(classType); this.isAnonymous = IsAnonymousType(classType);
} }
@ -271,8 +273,6 @@ namespace MongoDB.Bson.DefaultSerializer {
BsonClassMap.LookupClassMap(knownTypeAttribute.KnownType); // will AutoMap KnownType if necessary BsonClassMap.LookupClassMap(knownTypeAttribute.KnownType); // will AutoMap KnownType if necessary
} }
var conventions = GetConventionProfile(classType);
var discriminatorAttribute = (BsonDiscriminatorAttribute) classType.GetCustomAttributes(typeof(BsonDiscriminatorAttribute), false).FirstOrDefault(); var discriminatorAttribute = (BsonDiscriminatorAttribute) classType.GetCustomAttributes(typeof(BsonDiscriminatorAttribute), false).FirstOrDefault();
if (discriminatorAttribute != null) { if (discriminatorAttribute != null) {
discriminator = discriminatorAttribute.Discriminator; discriminator = discriminatorAttribute.Discriminator;
@ -453,16 +453,7 @@ namespace MongoDB.Bson.DefaultSerializer {
// if no base class provided an idPropertyMap maybe we have one? // if no base class provided an idPropertyMap maybe we have one?
if (idPropertyMap == null) { 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 namespace MongoDB.Bson.DefaultSerializer.Conventions
{ {
public sealed class ConventionProfile { public sealed class ConventionProfile {
public static ConventionProfile Default { get; set; }
public static ConventionProfile Default { get; private set; }
public IElementNameConvention ElementNameConvention { 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; ElementNameConvention = convention;
return this; 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>
<ItemGroup> <ItemGroup>
<Compile Include="DefaultSerializer\BsonClassMapTests.cs" /> <Compile Include="DefaultSerializer\BsonClassMapTests.cs" />
<Compile Include="DefaultSerializer\Conventions\IdPropertyConventionsTests.cs" />
<Compile Include="DefaultSerializer\Conventions\ElementNameConventionsTests.cs" /> <Compile Include="DefaultSerializer\Conventions\ElementNameConventionsTests.cs" />
<Compile Include="DefaultSerializer\SerializeFlagsTests.cs" /> <Compile Include="DefaultSerializer\SerializeFlagsTests.cs" />
<Compile Include="IO\BsonBufferValueStraddlesChunksTests.cs" /> <Compile Include="IO\BsonBufferValueStraddlesChunksTests.cs" />

2
BsonUnitTests/DefaultSerializer/BsonClassMapTests.cs

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