Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSHARP-1907: Add support for interface discriminators #1246

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

LucStr
Copy link

@LucStr LucStr commented Jan 14, 2024

Hello everyone

In this PR I am trying to address the challenge of using interfaces as root objects in MongoDB and BSON respectively. I am trying to address this issue. MongoDB does not support discriminating against interface types, only against ClassTypes.

Besides the serialization, this change also allows for the support of using the .OfType(). meaning that collections can now discriminate against the actual interfaces implemented.

I've added tests for the serialization, but could not figure out where I would write integration tests for the .OfType part.

Additionally I would like some guidance in how to proceed with breaking changes as the changes introduced break some tests, specifically CSharp564Tests, looking at the described issue in Jira I do not think I am breaking the implementation there, simply the value of _t has changed to include more information.

I've used this code to test the implementation of ".OfType()":

public interface IAnimal
{
    public ObjectId Id { get; set; }
    public int Age { get; set; }
    public string Name { get; set; }
}

public class Bear : IAnimal
{
    public ObjectId Id { get; set; }
    public int Age { get; set; }
    public string Name { get; set; }
}

public interface  ICat : IAnimal
{
}

public class Tiger : ICat
{
    public ObjectId Id { get; set; }
    public int Age { get; set; }
    public string Name { get; set; }
}

public class Lion : ICat
{
    public ObjectId Id { get; set; }
    public int Age { get; set; }
    public string Name { get; set; }
}

public class Program
{
    public static void Main(params string[] args)
    {
        BsonSerializer.RegisterSerializer(new DiscriminatedInterfaceSerializer<IAnimal>(new InterfaceDiscriminatorConvention<IAnimal>("_t")));
        BsonClassMap.RegisterClassMap<Bear>();
        BsonClassMap.RegisterClassMap<Tiger>();
        BsonClassMap.RegisterClassMap<Lion>();


        var client = new MongoClient();
        var collection = client.GetDatabase("test").GetCollection<IAnimal>("animal");

        collection.DeleteMany(x => true);
        
        collection.InsertOne(new Bear()
        {
            Id = ObjectId.GenerateNewId(),
            Age = 1,
            Name = "Bob the bear",
        });
        
        
        collection.InsertOne(new Lion()
        {
            Id = ObjectId.GenerateNewId(),
            Age = 1,
            Name = "Leon the lion",
        });
        
        collection.InsertOne(new Tiger()
        {
            Id = ObjectId.GenerateNewId(),
            Age = 1,
            Name = "Theo the tiger",
        });
        
        var cats = client.GetDatabase("test").GetCollection<IAnimal>("animal").OfType<ICat>().Find(x => true).ToList();

        foreach (var cat in cats)
        {
            Console.WriteLine(cat.Name);   
        }

    }
}

@LucStr LucStr requested a review from a team as a code owner January 14, 2024 21:31
@LucStr LucStr requested review from adelinowona and removed request for a team January 14, 2024 21:31
@adelinowona adelinowona requested review from JamesKovacs and rstam and removed request for adelinowona January 19, 2024 22:22
@rstam rstam removed their request for review March 14, 2024 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant