[CSHARP-1643] Differencies in how new Driver handle custom serialization Created: 02/May/16  Updated: 02/Jun/22  Resolved: 16/Jan/18

Status: Closed
Project: C# Driver
Component/s: Serialization
Affects Version/s: 2.2.3
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Gian Maria Ricci Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to CSHARP-2150 RegisterSerializer should check that ... Backlog

 Description   

I've setup a simple test to repro the problem here https://github.com/alkampfergit/MongoDbNewDriverTest

If you create a class implementing IBsonSerializer in the old driver to control serialization of a series of class based on a base class, everything is ok.

I have base class EventStoreIdentity then a GroupId and a UserId both inheriting from that class. I instruct driver to use custom serializer

BsonSerializer.RegisterSerializer(typeof(GroupId), new EventStoreIdentityBsonSerializer());

Then I declare a class that uses GroupId, No problem

  public class ObjectWithArrayOfIdentities
    {
        public String Id { get; set; }
 
        public GroupId[] Groups { get; set; }
    }

then I have a class that declares an array with that type and the new driver is not able to serialize the object anymore.

  public class ObjectWithArrayOfIdentities
    {
        public String Id { get; set; }
 
        public GroupId[] Groups { get; set; }
    }

It throws Unable to cast object of type 'NewDriver.Serializer.EventStoreIdentityBsonSerializer' to type 'MongoDB.Bson.Serialization.IBsonSerializer`1[CommonTestClasses.GroupId]'.

With the old driver there is no problem in doing the same operation, it is able to serialize everything correctly.

The same happens with classes that declare property using base class or generics (the new driver is not able to serialize them)

 public class ObjectWithGenericIdentity<T> where T : EventStoreIdentity
    {
        public String Id { get; set; }
 
        public T RelatedId { get; set; }
    }

There are some workaround to avoid this problem, as an example creating a typed serializer that is able to serialize array, but it would be nice if the new driver behaves the same as the old one.



 Comments   
Comment by Robert Stam [ 16/Jan/18 ]

I don't think the problem is related to arrays, but rather to the fact that serializers are expected to be for a single type. This was always expected, but the driver is more strict about it now. In your repro the problem is with the following line:

BsonSerializer.RegisterSerializer(typeof(GroupId), new EventStoreIdentityBsonSerializer());

You are registering a serializer for GroupId, but EventStoreIdentityBsonSerializer is not a serializer for GroupId, it is a serializer for EventStoreIdentity.

It is unfortunate that we don't catch this mismatch at the time you register the serializer, but only at the time you attempt to serialize something. I've created a new JIRA issue to track the changed needed to RegisterSerializer.

Comment by Gian Maria Ricci [ 19/Aug/16 ]

I've tried to execute again my test project https://github.com/alkampfergit/MongoDbNewDriverTest after a fresh clone and against a MongoDb 3.2 instance, and verify_serialization_array Unit tests passes with the old driver, but fails with the new driver.

I'm curious to know why it is working for you.

Comment by Craig Wilson [ 18/Aug/16 ]

Gian Maria,

Sorry for the late reply. It's troubling that an array doesn't simply work for you. I haven't been able to reproduce this behavior. If this is still a problem, could you provide a repro script?

Yes, we understand the difficulties in updating large projects. As I said, some things just had to be broken. Most users don't create custom serializers, so the number of users this affects are small, but those can get hit pretty hard if they were doing a lot of this low-level work.

Craig

Comment by Gian Maria Ricci [ 16/May/16 ]

Basically speaking, if I have a serializer for type T, with the old driver it works even when an object has a property that is an Array of T. With the new driver this seems not to work anymore.

Actually it is not difficult to convert to the new driver interface, but when you have a large project, converting to the new driver, with the huge amount of breaking changes, it is a real annoying

If you have a good amount of unit testing the task is easier, but in project without unit testing, these kind of differencies are a little bit dangerous.

Gian Maria.

Comment by Craig Wilson [ 16/May/16 ]

There are certain changes we need to make in the 2.x version of the driver. While we did attempt to keep as much backwards compatibility as possible, some things simply had to break. For instance, if you had a custom serializer, then it will need to implement the generic IBsonSerializer interface.

If I'm not fully understanding the problem, could you please try to re-explain?

Thanks,
Craig

Generated at Wed Feb 07 21:40:15 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.