Deserialize IList<IInterface> property?

291 views
Skip to first unread message

robert...@carvana.com

unread,
Nov 12, 2016, 10:10:16 PM11/12/16
to mongodb-user

This works for me:
        [BsonSerializer(typeof(ImpliedImplementationInterfaceSerializer<IReviewExpert, ReviewExpert>))]
       
public IReviewExpert Expert { get; set; }


But I can't find a serializer that will work for IList<Interface>.

public IList<IReviewSection> Sections { get; set; }


The problem is the mongo collection was/is populated not using a mongo mapping class and I can't change it in the near future.
 So I need to tell Mongo which class to use for the interface because there is no Discriminator in the collection.

This does not work, thrown an exception cannot create abstract class. There is no abstract classes nor classes which Inherit others. My classes just implement interfaces.


[BsonSerializer(typeof(EnumerableSerializerBase<List<ReviewSection>>))]

public IList<IReviewSection> Sections { get; set; }


Anyone know which serializer will work without changing the interfaces or existing collection?

Robert Stam

unread,
Nov 14, 2016, 11:18:16 AM11/14/16
to mongod...@googlegroups.com
I don't think you can do that with attributes, but you should be able to configure it in code like this:

var classMap = BsonClassMap.RegisterClassMap<C>(cm =>
{
    cm.AutoMap();
    var reviewSectionSerializer = new ImpliedImplementationInterfaceSerializer<IReviewSection, ReviewSection>();
    var listSerializer = new EnumerableInterfaceImplementerSerializer<List<IReviewSection>, IReviewSection>(reviewSectionSerializer);
    var listInterfaceSerializer = new ImpliedImplementationInterfaceSerializer<IList<IReviewSection>, List<IReviewSection>>(listSerializer);
    cm.GetMemberMap(x => x.Sections).SetSerializer(listInterfaceSerializer);
});

The steps are:

1. Use AutoMap to set up the class (we'll then override the serializer for Sections below)
2. Create a serializer for type IReviewSection with an implied implementation of ReviewSection (so it will be written and read without discriminators)
3. Create a serializer for type List<IReviewSection> to do the actual work of serializing the list
4. Create a serializer for type IList<IReviewSection> with an implied implementation of List<IReviewSection> (so it will be written and read without discriminators)
5. Configure this last serializer to be the serializer for the Sections property


--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user+unsubscribe@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/a7b9258b-2c90-41f8-9f9c-d979bcd409cf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

robert...@carvana.com

unread,
Nov 14, 2016, 7:01:54 PM11/14/16
to mongodb-user
Thank you!

That worked.

I made this helper method to make it generic:

        private static ImpliedImplementationInterfaceSerializer<IList<T>, List<T>> ListOfInterfacesSerializer<T, TI>() where TI : class, T
       
{
           
var serializer = new ImpliedImplementationInterfaceSerializer<T, TI>();
           
var listSerializer =
               
new EnumerableInterfaceImplementerSerializer<List<T>, T>(serializer);
           
return new ImpliedImplementationInterfaceSerializer<IList<T>, List<T>>(
                    listSerializer
);
       
}

// Usage example
            BsonClassMap.RegisterClassMap<Review>(cm =>
            {
                cm.AutoMap();
                cm.MapMember(x => x.Sections)
                    .SetSerializer(ListOfInterfacesSerializer<IReviewSection, ReviewSection>());
            });



To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.

robert...@carvana.com

unread,
Nov 14, 2016, 7:22:15 PM11/14/16
to mongodb-user
I have one more question:

// What I want my POCO to look like:
IDictionary<RatingType, double> Ratings { get; set; }


public enum RatingType
{
   
Comfort,
   
Reliabllity,
   
Performance
}


What my mongo collection looks like: 





Same deal as before. I need to keep the mongo data structure the same but serialize and deserialize as an IDictionary<RatingType, decimal> instead.

I tried setting the dictionary serilizer to arrayofDocuments but it complains about "name" and "value"

Is this possible? If not, it's not a big deal.

Currently I do:

  public interface IReviewRating
 
{
   
string Name { get; set; }
   
double Value { get; set; }
 
}

 
IList<IRreviewRating> Ratings {get; set;}

Reply all
Reply to author
Forward
0 new messages