I'm attempting to avoid introducing any dependencies between my Data layer and client code that makes use of this layer, but am running into some problems when attempting to do this with Mongo (using the MongoRepository)
MongoRepository shows examples where you create Types that reflect your data structure, and inherit Entity where required. Eg.
[CollectionName("track")]
public class Track : Entity
{
public string name { get; set; }
public string hash { get; set; }
public Artist artist { get; set; }
public List<Publish> published {get; set;}
public List<Occurence> occurence {get; set;}
}
In order to make use of these in my client code, I'd like to replace the Mongo-specific types with Interfaces, e.g:
[CollectionName("track")]
public class Track : Entity, ITrackEntity
{
public string name { get; set; }
public string hash { get; set; }
public IArtistEntity artist { get; set; }
public List<IPublishEntity> published {get; set;}
public List<IOccurenceEntity> occurence {get; set;}
}
However, the Mongo driver doesn't know how to treat these interfaces, and I understandably get the following error:
An error occurred while deserializing the artist property of class sf.data.mongodb.entities.Track: No serializer found for type sf.data.IArtistEntity. ---> MongoDB.Bson.BsonSerializationException: No serializer found for type sf.data.IArtistEntity.
Does anyone have any suggestions about how I should approach this?
Okay - so I found the answer to my own question - and thought I'd share in case anyone has a similar problem
The feature I was looking for was BsonClassMap.RegisterClassMap
This allows you to explicitly define which properties / fields of your domain classes should be serialized / deserialized (note it replaces any automapping - you need to define all fields / properties you wish to include). It resolved the issue of deserializing to a property with an Interface type with no further problems.
BsonClassMap.RegisterClassMap<Track>(cm =>
{
cm.MapProperty<IArtistEntity>(c => (IArtistEntity)c.Artist);
cm.MapProperty<List<IOccurenceEntity>>(c => (List<IOccurenceEntity>)c.Occurence);
cm.MapProperty(c => c.hash);
cm.MapProperty(c => c.name);
cm.MapProperty(c => c.published);
});