Created
June 21, 2019 10:14
-
-
Save SzymonPobiega/6730b2275847b0fb7b90339e7e751bb9 to your computer and use it in GitHub Desktop.
This file contains 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
namespace NServiceBus.AcceptanceTests.Sagas | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using EndpointTemplates; | |
using AcceptanceTesting; | |
using global::NHibernate.Cfg; | |
using global::NHibernate.Dialect; | |
using global::NHibernate.Driver; | |
using global::NHibernate.Mapping.ByCode; | |
using global::NHibernate.Mapping.ByCode.Conformist; | |
using NUnit.Framework; | |
using Persistence; | |
using Environment = global::NHibernate.Cfg.Environment; | |
public class When_saga_contains_polymorphic_collection : NServiceBusAcceptanceTest | |
{ | |
[Test] | |
public async Task Should_persist_correctly() | |
{ | |
var result = await Scenario.Define<Context>(c => c.Id = Guid.NewGuid()) | |
.WithEndpoint<NHNestedCollectionEndpoint>(b => b.When(async (bus, context) => | |
{ | |
await bus.SendLocal(new Message1 | |
{ | |
SomeId = context.Id | |
}).ConfigureAwait(false); | |
})) | |
.Done(c => c.Done) | |
.Run(); | |
Assert.IsTrue(result.Done); | |
Assert.AreEqual(5, result.CircleDiameter); | |
Assert.AreEqual(7, result.SquareSideLength); | |
} | |
public class Context : ScenarioContext | |
{ | |
public Guid Id { get; set; } | |
public bool Done { get; set; } | |
public decimal SquareSideLength { get; set; } | |
public decimal CircleDiameter { get; set; } | |
} | |
public class NHNestedCollectionEndpoint : EndpointConfigurationBuilder | |
{ | |
public NHNestedCollectionEndpoint() | |
{ | |
EndpointSetup<DefaultServer>(c => | |
{ | |
var cfg = new Configuration(); | |
cfg.SetProperty(Environment.Dialect, typeof(MsSql2012Dialect).FullName); | |
cfg.SetProperty(Environment.ConnectionDriver, typeof(Sql2008ClientDriver).FullName); | |
cfg.SetProperty(Environment.ConnectionString, EndpointConfigurer.ConnectionString); | |
var mapper = new ModelMapper(); | |
mapper.AddMapping(typeof(ShapeElementMap)); | |
mapper.AddMapping(typeof(ShapeElementMap.CircleElementMap)); | |
mapper.AddMapping(typeof(ShapeElementMap.SquareElementMap)); | |
mapper.AddMapping(typeof(PolymorphicCollectionSagaDataMap)); | |
cfg.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); | |
c.UsePersistence<NHibernatePersistence>().UseConfiguration(cfg); | |
c.LimitMessageProcessingConcurrencyTo(1); | |
}); | |
} | |
public class NHNestedCollectionSaga : Saga<PolymorphicCollectionSagaData>, IHandleMessages<Message2>, IAmStartedByMessages<Message1> | |
{ | |
public Context ScenarioContext { get; set; } | |
protected override void ConfigureHowToFindSaga(SagaPropertyMapper<PolymorphicCollectionSagaData> mapper) | |
{ | |
mapper.ConfigureMapping<Message2>(m => m.SomeId).ToSaga(s => s.SomeId); | |
mapper.ConfigureMapping<Message1>(m => m.SomeId).ToSaga(s => s.SomeId); | |
} | |
public Task Handle(Message1 message, IMessageHandlerContext context) | |
{ | |
Data.SomeId = message.SomeId; | |
Data.RelatedData.Add(new CircleElement | |
{ | |
Diameter = 5, | |
}); | |
Data.RelatedData.Add(new SquareElement | |
{ | |
SideLength = 7, | |
}); | |
return context.SendLocal(new Message2 | |
{ | |
SomeId = message.SomeId | |
}); | |
} | |
public Task Handle(Message2 message, IMessageHandlerContext context) | |
{ | |
var square = Data.RelatedData.OfType<SquareElement>().First(); | |
ScenarioContext.SquareSideLength = square.SideLength; | |
var circle = Data.RelatedData.OfType<CircleElement>().First(); | |
ScenarioContext.CircleDiameter = circle.Diameter; | |
ScenarioContext.Done = true; | |
return Task.CompletedTask; | |
} | |
} | |
} | |
public class PolymorphicCollectionSagaData : IContainSagaData | |
{ | |
public virtual Guid Id { get; set; } | |
public virtual string Originator { get; set; } | |
public virtual string OriginalMessageId { get; set; } | |
public virtual Guid SomeId { get; set; } | |
public virtual IList<ShapeElement> RelatedData { get; set; } = new List<ShapeElement>(); | |
} | |
public class Message2 : IMessage | |
{ | |
public Guid SomeId { get; set; } | |
} | |
public class Message1 : IMessage | |
{ | |
public Guid SomeId { get; set; } | |
} | |
public class PolymorphicCollectionSagaDataMap : ClassMapping<PolymorphicCollectionSagaData> | |
{ | |
public PolymorphicCollectionSagaDataMap() | |
{ | |
Id(x => x.Id, m => m.Generator(Generators.Assigned)); | |
Table("PolymorphicCollectionSagaData"); | |
Property(x => x.Originator); | |
Property(x => x.OriginalMessageId); | |
Property(x => x.SomeId); | |
Bag(x => x.RelatedData, m => | |
{ | |
m.Cascade(Cascade.All); | |
}, m => m.OneToMany()); | |
} | |
} | |
public class ShapeElementMap : ClassMapping<ShapeElement> | |
{ | |
public ShapeElementMap() | |
{ | |
Id(x => x.Id, m => m.Generator(Generators.Guid)); | |
Abstract(true); | |
Discriminator(m => m.Column("type")); | |
Table("ShapeElement"); | |
} | |
public class CircleElementMap : SubclassMapping<CircleElement> | |
{ | |
public CircleElementMap() | |
{ | |
DiscriminatorValue("circle"); | |
Property(x => x.Diameter); | |
} | |
} | |
public class SquareElementMap : SubclassMapping<SquareElement> | |
{ | |
public SquareElementMap() | |
{ | |
DiscriminatorValue("square"); | |
Property(x => x.SideLength); | |
} | |
} | |
} | |
public abstract class ShapeElement | |
{ | |
public virtual Guid Id { get; set; } | |
} | |
public class CircleElement : ShapeElement | |
{ | |
public virtual decimal Diameter { get; set; } | |
} | |
public class SquareElement : ShapeElement | |
{ | |
public virtual decimal SideLength { get; set; } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment