using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ModelBinding; using MongoDB.Bson; using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Conventions; using Wabbajack.BuildServer.Models.JobQueue; using Wabbajack.Lib.Downloaders; namespace Wabbajack.BuildServer { public static class SerializerSettings { public static void Init() { var dis = new TypeDiscriminator(typeof(AbstractDownloadState), AbstractDownloadState.NameToType, AbstractDownloadState.TypeToName); BsonSerializer.RegisterDiscriminatorConvention(typeof(AbstractDownloadState), dis); BsonClassMap.RegisterClassMap(cm => cm.SetIsRootClass(true)); dis = new TypeDiscriminator(typeof(AJobPayload), AJobPayload.NameToType, AJobPayload.TypeToName); BsonSerializer.RegisterDiscriminatorConvention(typeof(AJobPayload), dis); BsonClassMap.RegisterClassMap(cm => cm.SetIsRootClass(true)); } } public class TypeDiscriminator : IDiscriminatorConvention { private readonly Type defaultType; private readonly Dictionary typeMap; private Dictionary revMap; public TypeDiscriminator(Type defaultType, Dictionary typeMap, Dictionary revMap) { this.defaultType = defaultType; this.typeMap = typeMap; this.revMap = revMap; } /// /// Element Name /// public string ElementName => "_wjType"; public Type GetActualType(IBsonReader bsonReader, Type nominalType) { Type type = null; var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); if (bsonReader.FindElement(ElementName)) { var value = bsonReader.ReadString(); if (typeMap.ContainsKey(value)) type = typeMap[value]; } bsonReader.ReturnToBookmark(bookmark); if (type == null) throw new Exception($"Type mis-configuration can't find bson type for ${nominalType}"); return type; } public BsonValue GetDiscriminator(Type nominalType, Type actualType) { return revMap[actualType]; } } }