// public methods /// <summary> /// Gets the actual type of an object by reading the discriminator from a BsonReader. /// </summary> /// <param name="bsonReader">The reader.</param> /// <param name="nominalType">The nominal type.</param> /// <returns>The actual type.</returns> public Type GetActualType(IBsonReader bsonReader, Type nominalType) { // the BsonReader is sitting at the value whose actual type needs to be found var bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Document) { // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer) BsonSerializer.EnsureKnownTypesAreRegistered(nominalType); // we can skip looking for a discriminator if nominalType has no discriminated sub types if (BsonSerializer.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; if (bsonReader.FindElement(_elementName)) { var context = BsonDeserializationContext.CreateRoot <BsonValue>(bsonReader); var discriminator = BsonValueSerializer.Instance.Deserialize(context); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return(actualType); } } return(nominalType); }
/***************************************************/ /**** Interface Methods ****/ /***************************************************/ public Type GetActualType(IBsonReader bsonReader, Type nominalType) { Type actualType = nominalType; // the BsonReader is sitting at the value whose actual type needs to be found BsonType bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Document) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); if (bsonReader.FindElement(ElementName)) { var context = BsonDeserializationContext.CreateRoot(bsonReader); var discriminator = BsonValueSerializer.Instance.Deserialize(context); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } if (BsonSerializer.IsTypeDiscriminated(nominalType)) { actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } } bsonReader.ReturnToBookmark(bookmark); } return(actualType); }
private static void Mapper() { if (!BsonClassMap.IsClassMapRegistered(typeof(Event))) { BsonClassMap.RegisterClassMap <Event>(x => { x.AutoMap(); x.MapProperty(p => p.RequestID); x.MapProperty(p => p.EventDate); }); } if (!BsonClassMap.IsClassMapRegistered(typeof(MemberCreatedEvent))) { BsonClassMap.RegisterClassMap <MemberCreatedEvent>(x => { x.AutoMap(); x.MapProperty(p => p.ID); x.MapProperty(p => p.LegacyID); x.MapProperty(p => p.Age); x.MapProperty(p => p.CellNumber); x.MapProperty(p => p.DateOfBirth); x.MapProperty(p => p.EventType); x.MapProperty(p => p.FullName); x.MapCreator(m => new MemberCreatedEvent(m.ID, m.LegacyID, m.FullName, m.Age, m.CellNumber, m.DateOfBirth, m.RequestID, m.EventDate)); }); } if (!BsonClassMap.IsClassMapRegistered(typeof(MemberUpdatedEvent))) { BsonClassMap.RegisterClassMap <MemberUpdatedEvent>(x => { x.AutoMap(); x.MapProperty(p => p.ID); x.MapProperty(p => p.LegacyID); x.MapProperty(p => p.Age); x.MapProperty(p => p.CellNumber); x.MapProperty(p => p.DateOfBirth); x.MapProperty(p => p.EventType); x.MapProperty(p => p.FullName); x.MapCreator(m => new MemberUpdatedEvent(m.ID, m.LegacyID, m.FullName, m.Age, m.CellNumber, m.DateOfBirth, m.RequestID, m.EventDate)); }); } if (!BsonSerializer.IsTypeDiscriminated(typeof(DateTimeSerializer))) { BsonSerializer.RegisterSerializer(typeof(DateTime), new DateTimeSerializer(DateTimeKind.Local)); } }
/***************************************************/ /**** Interface Methods ****/ /***************************************************/ public Type GetActualType(IBsonReader bsonReader, Type nominalType) { Type actualType = nominalType; // the BsonReader is sitting at the value whose actual type needs to be found BsonType bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Document) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); if (bsonReader.FindElement(ElementName)) { var context = BsonDeserializationContext.CreateRoot(bsonReader); var discriminator = BsonValueSerializer.Instance.Deserialize(context); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } if (BsonSerializer.IsTypeDiscriminated(nominalType)) { actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } else if (Reflection.Compute.UnqualifiedName(nominalType.FullName) != Reflection.Compute.UnqualifiedName(discriminator.ToString()) && Config.AllowUpgradeFromBson && !Config.TypesWithoutUpgrade.Contains(actualType)) { actualType = typeof(IDeprecated); } } bsonReader.ReturnToBookmark(bookmark); if (Config.AllowUpgradeFromBson && actualType.IsDeprecated() && !Config.TypesWithoutUpgrade.Contains(actualType)) { actualType = typeof(IDeprecated); } } return(actualType); }
public void verify_reloading_with_snapshot() { //create an aggregate. var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); for (int i = 0; i < NumberOfCommitsBeforeSnapshot; i++) { ((IAggregateEx)aggregate).ApplyEvent(new SampleAggregateTouched()); } _sut.SnapshotManager = new CachedSnapshotManager( new MongoSnapshotPersisterProvider(_db, NullLogger.Instance), new NullSnapshotPersistenceStrategy()); //this will save the snapshot _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); var discriminated = BsonSerializer.IsTypeDiscriminated(typeof(AggregateSnapshot <>)); Console.WriteLine("Discriminated: {0}", discriminated); //now reload the aggregate var reloaded = _sut.GetById <SampleAggregate>(sampleAggregateId); Assert.That(reloaded.SnapshotRestoreVersion, Is.EqualTo(51)); }
// public methods /// <summary> /// Gets the actual type of an object by reading the discriminator from a BsonReader. /// </summary> /// <param name="bsonReader">The reader.</param> /// <param name="nominalType">The nominal type.</param> /// <returns>The actual type.</returns> public Type GetActualType(BsonReader bsonReader, Type nominalType) { // the BsonReader is sitting at the value whose actual type needs to be found var bsonType = bsonReader.GetCurrentBsonType(); if (bsonReader.State == BsonReaderState.Value) { Type primitiveType = null; switch (bsonType) { case BsonType.Boolean: primitiveType = typeof(bool); break; case BsonType.Binary: var bookmark = bsonReader.GetBookmark(); var binaryData = bsonReader.ReadBinaryData(); var subType = binaryData.SubType; if (subType == BsonBinarySubType.UuidStandard || subType == BsonBinarySubType.UuidLegacy) { primitiveType = typeof(Guid); } bsonReader.ReturnToBookmark(bookmark); break; case BsonType.DateTime: primitiveType = typeof(DateTime); break; case BsonType.Double: primitiveType = typeof(double); break; case BsonType.Int32: primitiveType = typeof(int); break; case BsonType.Int64: primitiveType = typeof(long); break; case BsonType.ObjectId: primitiveType = typeof(ObjectId); break; case BsonType.String: primitiveType = typeof(string); break; } // Type.IsAssignableFrom is extremely expensive, always perform a direct type check before calling Type.IsAssignableFrom if (primitiveType != null && (primitiveType == nominalType || nominalType.IsAssignableFrom(primitiveType))) { return(primitiveType); } } if (bsonType == BsonType.Document) { // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer) BsonSerializer.EnsureKnownTypesAreRegistered(nominalType); // we can skip looking for a discriminator if nominalType has no discriminated sub types if (BsonSerializer.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; if (bsonReader.FindElement(_elementName)) { var discriminator = (BsonValue)BsonValueSerializer.Instance.Deserialize(bsonReader, typeof(BsonValue), null); if (discriminator.IsBsonArray) { discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator } actualType = BsonSerializer.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return(actualType); } } return(nominalType); }
/// <summary> /// If the type is not registered, attach it to our discriminator /// </summary> /// <param name="actualType">the type to examine</param> protected void RegisterNewTypesToDiscriminator(Type actualType) { // we've detected a new concrete type that isn't registered in MongoDB's serializer if (actualType != typeof(object) && !actualType.GetTypeInfo().IsInterface&& !BsonSerializer.IsTypeDiscriminated(actualType)) { try { BsonSerializer.RegisterDiscriminatorConvention(actualType, DiscriminatorConvention); BsonSerializer.RegisterDiscriminator(actualType, DiscriminatorConvention.GetDiscriminator(typeof(object), actualType)); } catch (BsonSerializationException) { // the MongoDB driver library has no nice mechanism for checking if a discriminator convention is registerd. // The "Lookup" logic tends to define a default if it doesn't exist. // So we're forced to eat the "duplicate registration" exception. } } }