Skip to content

Commit

Permalink
Fixed CSHARP-263. Changed BsonBaseSerializer to require that all subc…
Browse files Browse the repository at this point in the history
…lasses implement the overload of Deserialize that inludes an actualType parameter. When an array is serialized and nominalType is object it now wraps the array in a document that includes type information ("_t" and "_v" elements).
  • Loading branch information
rstam committed Aug 9, 2011
1 parent 186e2e7 commit 428ef0a
Show file tree
Hide file tree
Showing 16 changed files with 647 additions and 165 deletions.
307 changes: 174 additions & 133 deletions Bson/Serialization/Serializers/ArraySerializer.cs

Large diffs are not rendered by default.

29 changes: 26 additions & 3 deletions Bson/Serialization/Serializers/BsonBaseSerializer.cs
Expand Up @@ -49,7 +49,8 @@ public abstract class BsonBaseSerializer : IBsonSerializer {
Type nominalType,
IBsonSerializationOptions options
) {
throw new NotSupportedException("Subclass must implement Deserialize.");
// override this method to determine actualType if your serializer handles polymorphic data types
return Deserialize(bsonReader, nominalType, nominalType, options);
}

/// <summary>
Expand All @@ -63,10 +64,10 @@ IBsonSerializationOptions options
public virtual object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType, // ignored
Type actualType,
IBsonSerializationOptions options
) {
return Deserialize(bsonReader, nominalType, options);
throw new NotSupportedException("Subclass must implement Deserialize.");
}

/// <summary>
Expand Down Expand Up @@ -114,5 +115,27 @@ object id
throw new NotSupportedException("Subclass must implement SetDocumentId.");
}
#endregion

#region protected methods
/// <summary>
/// Verifies the nominal and actual types against the expected type.
/// </summary>
/// <param name="nominalType">The nominal type.</param>
/// <param name="actualType">The actual type.</param>
/// <param name="expectedType">The expected type.</param>
protected void VerifyTypes(
Type nominalType,
Type actualType,
Type expectedType
) {
if (actualType != expectedType) {
var message = string.Format("{0} can only be used with type {1}, not with type {2}.", this.GetType().FullName, expectedType.FullName, actualType.FullName);
throw new BsonSerializationException(message);
}
if (!nominalType.IsAssignableFrom(actualType)) {
var message = string.Format("{0} can only be used with a nominal type that is assignable from the actual type {1}, but nominal type {2} is not.", this.GetType().FullName, actualType.FullName, nominalType.FullName);
}
}
#endregion
}
}
32 changes: 32 additions & 0 deletions Bson/Serialization/Serializers/BsonPrimitiveSerializers.cs
Expand Up @@ -58,13 +58,17 @@ public class BooleanSerializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(bool));

var bsonType = bsonReader.CurrentBsonType;
switch (bsonType) {
case BsonType.Boolean:
Expand Down Expand Up @@ -156,13 +160,17 @@ public class DateTimeSerializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(DateTime));

var dateTimeOptions = (options == null) ? DateTimeSerializationOptions.Defaults : (DateTimeSerializationOptions) options;
DateTime value;

Expand Down Expand Up @@ -314,13 +322,17 @@ public class DoubleSerializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(double));

var representationOptions = (RepresentationSerializationOptions) options ?? defaultRepresentationOptions;
var bsonType = bsonReader.CurrentBsonType;
switch (bsonType) {
Expand Down Expand Up @@ -405,13 +417,17 @@ public class GuidSerializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(Guid));

var bsonType = bsonReader.CurrentBsonType;
string message;
switch (bsonType) {
Expand Down Expand Up @@ -509,13 +525,17 @@ public class Int32Serializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(int));

var representationOptions = (RepresentationSerializationOptions) options ?? defaultRepresentationOptions;
var bsonType = bsonReader.CurrentBsonType;
switch (bsonType) {
Expand Down Expand Up @@ -601,13 +621,17 @@ public class Int64Serializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(long));

var representationOptions = (RepresentationSerializationOptions) options ?? defaultRepresentationOptions;
var bsonType = bsonReader.CurrentBsonType;
switch (bsonType) {
Expand Down Expand Up @@ -692,13 +716,17 @@ public class ObjectIdSerializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(ObjectId));

BsonType bsonType = bsonReader.CurrentBsonType;
switch (bsonType) {
case BsonType.ObjectId:
Expand Down Expand Up @@ -776,13 +804,17 @@ public class StringSerializer : BsonBaseSerializer {
/// </summary>
/// <param name="bsonReader">The BsonReader.</param>
/// <param name="nominalType">The nominal type of the object.</param>
/// <param name="actualType">The actual type of the object.</param>
/// <param name="options">The serialization options.</param>
/// <returns>An object.</returns>
public override object Deserialize(
BsonReader bsonReader,
Type nominalType,
Type actualType,
IBsonSerializationOptions options
) {
VerifyTypes(nominalType, actualType, typeof(string));

var bsonType = bsonReader.CurrentBsonType;
if (bsonType == BsonType.Null) {
bsonReader.ReadNull();
Expand Down

0 comments on commit 428ef0a

Please sign in to comment.