Skip to content

Commit 8c4d787

Browse files
author
Robert Stam
committed
Merge branch 'master' of git://github.com/optimiz3/mongo-csharp-driver into csharp451
2 parents b2e03c7 + 288471f commit 8c4d787

File tree

4 files changed

+80
-30
lines changed

4 files changed

+80
-30
lines changed

Bson/Serialization/BsonClassMap.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public abstract class BsonClassMap
4747
private bool _frozen; // once a class map has been frozen no further changes are allowed
4848
private BsonClassMap _baseClassMap; // null for class object and interfaces
4949
private Type _classType;
50+
private volatile IDiscriminatorConvention _cachedDiscriminatorConvention;
5051
private Func<object> _creator;
5152
private ConventionProfile _conventions;
5253
private string _discriminator;
@@ -965,6 +966,22 @@ public void UnmapProperty(string propertyName)
965966
UnmapMember(propertyInfo);
966967
}
967968

969+
// internal methods
970+
/// <summary>
971+
/// Gets the discriminator convention for the member type.
972+
/// </summary>
973+
/// <returns>The discriminator convention for the member type.</returns>
974+
internal IDiscriminatorConvention GetDiscriminatorConvention()
975+
{
976+
var classDiscriminatorConvention = _cachedDiscriminatorConvention;
977+
if (classDiscriminatorConvention == null)
978+
{
979+
classDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(_classType);
980+
_cachedDiscriminatorConvention = classDiscriminatorConvention;
981+
}
982+
return classDiscriminatorConvention;
983+
}
984+
968985
// private methods
969986
private void AutoMapClass()
970987
{
@@ -1485,7 +1502,7 @@ public void UnmapProperty<TMember>(Expression<Func<TClass, TMember>> propertyLam
14851502
UnmapMember(propertyLambda);
14861503
}
14871504

1488-
// private methods
1505+
// private static methods
14891506
private static MemberInfo GetMemberInfoFromLambda<TMember>(Expression<Func<TClass, TMember>> memberLambda)
14901507
{
14911508
var body = memberLambda.Body;

Bson/Serialization/BsonClassMapSerializer.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializ
6363
}
6464
else
6565
{
66-
var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
66+
var discriminatorConvention = _classMap.GetDiscriminatorConvention();
6767
var actualType = discriminatorConvention.GetActualType(bsonReader, nominalType);
6868
if (actualType != nominalType)
6969
{
@@ -131,7 +131,7 @@ public object Deserialize(
131131

132132
bsonReader.ReadStartDocument();
133133
var missingElementMemberMaps = new HashSet<BsonMemberMap>(classMap.AllMemberMaps); // make a copy!
134-
var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
134+
var discriminatorConvention = classMap.GetDiscriminatorConvention();
135135
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
136136
{
137137
var elementName = bsonReader.ReadName();
@@ -337,7 +337,7 @@ public void Serialize(
337337
// never write out a discriminator for an anonymous class
338338
if (!classMap.IsAnonymous)
339339
{
340-
var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
340+
var discriminatorConvention = classMap.GetDiscriminatorConvention();
341341
var discriminator = discriminatorConvention.GetDiscriminator(nominalType, actualType);
342342
if (discriminator != null)
343343
{
@@ -443,7 +443,7 @@ private void DeserializeMember(BsonReader bsonReader, object obj, BsonMemberMap
443443
}
444444
else
445445
{
446-
var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
446+
var discriminatorConvention = memberMap.GetDiscriminatorConvention();
447447
actualType = discriminatorConvention.GetActualType(bsonReader, nominalType); // returns nominalType if no discriminator found
448448
}
449449
var serializer = memberMap.GetSerializer(actualType);

Bson/Serialization/BsonMemberMap.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public class BsonMemberMap
4444
private Action<object, object> _setter;
4545
private IBsonSerializationOptions _serializationOptions;
4646
private IBsonSerializer _serializer;
47+
private volatile IDiscriminatorConvention _cachedDiscriminatorConvention;
48+
private volatile IBsonSerializer _cachedSerializer;
4749
private IIdGenerator _idGenerator;
4850
private bool _isRequired;
4951
private Func<object, bool> _shouldSerializeMethod;
@@ -291,7 +293,20 @@ public IBsonSerializer GetSerializer(Type actualType)
291293
}
292294
else
293295
{
294-
return BsonSerializer.LookupSerializer(actualType);
296+
if (actualType == _memberType)
297+
{
298+
var cachedSerializer = _cachedSerializer;
299+
if (cachedSerializer == null)
300+
{
301+
cachedSerializer = BsonSerializer.LookupSerializer(_memberType);
302+
_cachedSerializer = cachedSerializer;
303+
}
304+
return cachedSerializer;
305+
}
306+
else
307+
{
308+
return BsonSerializer.LookupSerializer(actualType);
309+
}
295310
}
296311
}
297312

@@ -483,6 +498,22 @@ public bool ShouldSerialize(object obj, object value)
483498
return true;
484499
}
485500

501+
// internal methods
502+
/// <summary>
503+
/// Gets the discriminator convention for the member type.
504+
/// </summary>
505+
/// <returns>The discriminator convention for the member type.</returns>
506+
internal IDiscriminatorConvention GetDiscriminatorConvention()
507+
{
508+
var classDiscriminatorConvention = _cachedDiscriminatorConvention;
509+
if (classDiscriminatorConvention == null)
510+
{
511+
classDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(_memberType);
512+
_cachedDiscriminatorConvention = classDiscriminatorConvention;
513+
}
514+
return classDiscriminatorConvention;
515+
}
516+
486517
// private methods
487518
private static object GetDefaultValue(Type type)
488519
{

Bson/Serialization/BsonSerializer.cs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public static class BsonSerializer
4343
// static constructor
4444
static BsonSerializer()
4545
{
46-
RegisterDefaultSerializationProvider();
4746
RegisterIdGenerators();
4847
}
4948

@@ -359,7 +358,7 @@ public static IIdGenerator LookupIdGenerator(Type type)
359358
}
360359

361360
/// <summary>
362-
/// Looks up a serializer for a Type.
361+
/// Looks up and populates the serializer singleton for a type.
363362
/// </summary>
364363
/// <param name="type">The Type.</param>
365364
/// <returns>A serializer for the Type.</returns>
@@ -368,7 +367,7 @@ public static IBsonSerializer LookupSerializer(Type type)
368367
__configLock.EnterReadLock();
369368
try
370369
{
371-
IBsonSerializer serializer;
370+
IBsonSerializer serializer;
372371
if (__serializers.TryGetValue(type, out serializer))
373372
{
374373
return serializer;
@@ -385,6 +384,18 @@ public static IBsonSerializer LookupSerializer(Type type)
385384
IBsonSerializer serializer;
386385
if (!__serializers.TryGetValue(type, out serializer))
387386
{
387+
if (serializer == null)
388+
{
389+
foreach (var serializationProvider in __serializationProviders)
390+
{
391+
serializer = serializationProvider.GetSerializer(type);
392+
if (serializer != null)
393+
{
394+
break;
395+
}
396+
}
397+
}
398+
388399
// special case for IBsonSerializable
389400
if (serializer == null && typeof(IBsonSerializable).IsAssignableFrom(type))
390401
{
@@ -404,14 +415,7 @@ public static IBsonSerializer LookupSerializer(Type type)
404415

405416
if (serializer == null)
406417
{
407-
foreach (var serializationProvider in __serializationProviders)
408-
{
409-
serializer = serializationProvider.GetSerializer(type);
410-
if (serializer != null)
411-
{
412-
break;
413-
}
414-
}
418+
serializer = BsonDefaultSerializer.Instance.GetSerializer(type);
415419
}
416420

417421
if (serializer == null)
@@ -475,6 +479,11 @@ public static void RegisterIdGenerator(Type type, IIdGenerator idGenerator)
475479
/// <param name="provider">The serialization provider.</param>
476480
public static void RegisterSerializationProvider(IBsonSerializationProvider provider)
477481
{
482+
if (provider == BsonDefaultSerializer.Instance)
483+
{
484+
throw new ArgumentException("BsonDefaultSerializer is implicitly registered", "provider");
485+
}
486+
478487
__configLock.EnterWriteLock();
479488
try
480489
{
@@ -497,7 +506,12 @@ public static void RegisterSerializer(Type type, IBsonSerializer serializer)
497506
__configLock.EnterWriteLock();
498507
try
499508
{
500-
__serializers[type] = serializer;
509+
if (__serializers.ContainsKey(type))
510+
{
511+
var message = string.Format("There is already a serializer registered for type {0}.", type.FullName);
512+
throw new BsonSerializationException(message);
513+
}
514+
__serializers.Add(type, serializer);
501515
}
502516
finally
503517
{
@@ -555,24 +569,12 @@ public static void Serialize(
555569
object value,
556570
IBsonSerializationOptions options)
557571
{
558-
var bsonSerializable = value as IBsonSerializable;
559-
if (bsonSerializable != null)
560-
{
561-
bsonSerializable.Serialize(bsonWriter, nominalType, options);
562-
return;
563-
}
564-
565572
var actualType = (value == null) ? nominalType : value.GetType();
566573
var serializer = LookupSerializer(actualType);
567574
serializer.Serialize(bsonWriter, nominalType, value, options);
568575
}
569576

570577
// private static methods
571-
private static void RegisterDefaultSerializationProvider()
572-
{
573-
RegisterSerializationProvider(BsonDefaultSerializer.Instance);
574-
}
575-
576578
private static void RegisterIdGenerators()
577579
{
578580
BsonSerializer.RegisterIdGenerator(typeof(BsonObjectId), BsonObjectIdGenerator.Instance);

0 commit comments

Comments
 (0)