Last active
February 6, 2023 13:07
-
-
Save JamisonWhite/cc0eae9e0ebfe8e62ec3 to your computer and use it in GitHub Desktop.
C# MongoDb custom field and value discriminator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Map a resource "keyType" to polymorphic classes. | |
/// </summary> | |
/// <remarks> | |
/// Followed example here: | |
/// http://pastebin.com/9UweEKBe | |
/// </remarks> | |
public class CustomFieldDiscriminatorConvention : IDiscriminatorConvention | |
{ | |
private readonly string elementName; | |
private readonly Type defaultType; | |
private readonly Dictionary<string, Type> typeMap; | |
public CustomFieldDiscriminatorConvention(string elementName, Type defaultType, Dictionary<string, Type> typeMap) | |
{ | |
this.elementName = elementName; | |
this.defaultType = defaultType; | |
this.typeMap = typeMap; | |
} | |
/// <summary> | |
/// Element Name | |
/// </summary> | |
public string ElementName | |
{ | |
get { return elementName; } | |
} | |
/// <summary> | |
/// Return the type that matches the string | |
/// </summary> | |
/// <param name="bsonReader"></param> | |
/// <param name="nominalType"></param> | |
/// <returns></returns> | |
public Type GetActualType(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType) | |
{ | |
Type type = defaultType; | |
var bookmark = bsonReader.GetBookmark(); | |
bsonReader.ReadStartDocument(); | |
if (bsonReader.FindElement(ElementName)) | |
{ | |
var value = bsonReader.ReadString(); | |
if (typeMap.ContainsKey(value.ToLower())) | |
type = typeMap[value]; | |
} | |
bsonReader.ReturnToBookmark(bookmark); | |
return type; | |
} | |
public BsonValue GetDiscriminator(Type nominalType, Type actualType) | |
{ | |
return actualType.Name; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var dis = new CustomFieldDiscriminatorConvention( | |
"keyType", | |
typeof(Resource), | |
new Dictionary<string, Type>(3) | |
{ | |
{"domain", typeof (DomainResource)}, | |
{"ip", typeof (IpResource)}, | |
{"uri", typeof (UriResource)} | |
} | |
); | |
BsonSerializer.RegisterDiscriminatorConvention(typeof(Resource), dis); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@razzeee That makes sense, but I couldn't find a way to provide a default value for documents saved to the database before the discriminators were implemented using ScalarDiscriminatorConvention.