Deserialize object as an interface with MongoDB C# Driver

Gustavo Gondim picture Gustavo Gondim · Jan 28, 2013 · Viewed 10.3k times · Source

I am developing a project that uses MongoDB (with C# driver) and DDD.

I have a class (aggregate) which have a property which type is an interface. In another class, I have implemented this interface. This class has another property which type is an interface and is setted with another implemented class.

The code below explains better:

// Interfaces
public interface IUser {
    Guid Id { get; set;}
    IPartner Partner{ get; set; }
}

public interface IPartner {
    IPhone Mobile { get; set; }
}

public interface IPhone {
    string number { get; set; }
}

// Implemented Classes
public class User: IUser {
    [BsonId(IdGenerator = typeof(GuidGenerator))]
    public Guid Id { get; set; }

    [BsonIgnoreIfNull]
    public IPartner Partner { get; set; }
}

public struct Partner : IPartner {
    public IPhone Mobile { get; set; }
}

public struct Phone : IPhone {
    public string Number { get; set; }
}

Well, when I call the MongoCollection<User>.Insert() method, it throws two exceptions:

System.IO.FileFormatException: An error occurred while deserializing the Partner property of class .User: An error occurred while deserializing the Phone property of class .Partner: Value class .Mobile cannot be deserialized. ---> System.IO.FileFormatException: An error occurred while deserializing the Mobile property of class .Partner: Value class .Phone cannot be deserialized. ---> MongoDB.Bson.BsonSerializationException: Value class .Phone cannot be deserialized.

Then, I searched the internet for discover how to deserialize the type as an interface, and I think I have to ways to do it: mapping the property with a cast, using the BsonClassMap.RegisterClassMap or writing a custom BSON serializer.

I need to know which of these two ways is better and how to implement it.

Note: I need a solution that does not modify the interfaces, because theirs project cannot contain any external reference.

Answer

Gustavo Gondim picture Gustavo Gondim · Jan 28, 2013

Well, I have found a lot of problems when trying to get this answer.

First of all, the MongoDB C# Driver, does have some problems when deserializing interfaces, like said by Craig Wilson in this question comments, and as described in the issue page.

The secure implementation for this problem, like I said before, really may be a custom BSON serializer or a specific class map, using BsonClassMap.RegisterClassMap.

So, I have implemented the class map and the problem persisted.

Looking forward with the problem, I have found that exception is related to another issue of the driver: the problem when deserializing structs.

I have rolled back the project to the initial state (without classes map or custom serializers) and changed the struct type to class type, and it worked.

In resume, this exception error is related to structs deserialization, not with interfaces deserialization.


Anyway, it is a real problem, and the second issue needs to be considered more a bug than a improvement, like the first issue is.

You can find the issues at these links: