public void InheritedEventHandlerTest() { string firstAggregateId = "ar1"; string secondAggregateId = "ar2"; string firstCommandId = "c1"; string secondCommandId = "c2"; var item = new StockItem("item", "123"); string movementNumber = $"movement_{Guid.NewGuid()}"; var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>() .WithEventHandler <AdjustedIn, Adjustment>(e => e.EventBody.Adjustment); var options = new DomainOptions(DomainOption.CacheRuntimeModel); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, options); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>(firstCommandId, firstCommandId, firstAggregateId, new CreateLocation(firstAggregateId))); var results = engine.Process(CommandFactory.Default.CreateCommand <MoveIn>(secondCommandId, secondCommandId, firstAggregateId, new MoveIn(movementNumber, firstAggregateId, item, secondAggregateId))).ToList(); Assert.IsTrue(results.Any(r => r.EventBodyType == typeof(TransactionRecorded).FullName)); }
public BaseSpec() { var builder = new BoundedContextModelBuilder(); builder.UseInMemoryBuses(); builder.UseInMemoryEventStore(); builder.Aggregate <FlightReservation>(cfg => { cfg .WithId(c => c.Localizer) .CreatedBy <CreateFlightReservation>() .Executes <CancelFlightReservation>(c => c.Localizer); }); builder.Projection <ReservationViewProjection>(cfg => { cfg .WithState(c => c.LastEventId) .AutoSubscribe(); }); builder.ReadModel <ReservationView, ReservationViewRepository>(cfg => { cfg.RespondsTo <SearchReservationsByFlight>(c => c.Query); }); Model = builder.Build(); CommandBus = Model.Services.GetRequiredService <ICommandBus>(); Host = new Hosting.HostProcess(Model); Host.Start(); }
public void UnknowCommandThrowsExceptionTest() { var contextMap = new BoundedContextModel(); contextMap.WithAssembly(Assembly.GetExecutingAssembly().FullName); Assert.ThrowsException <ArgumentException>(() => (contextMap as IBoundedContextModel).GetAggregateType(typeof(CommandMock))); }
public void MapFindsProcessTest() { var contextMap = new BoundedContextModel(); contextMap.WithAssemblyContaining <Location>(); Assert.IsTrue(contextMap.IsEventHandlerType(typeof(Movement))); }
public void MapEventTest() { var contextMap = new BoundedContextModel(); contextMap.WithAssemblyContaining <Location>(); Assert.IsTrue(contextMap.IsEventType(typeof(LocationCreated))); Assert.IsFalse(contextMap.IsCommandType(typeof(LocationCreated))); }
public void MapFindsAggregateTest() { var contextMap = new BoundedContextModel(); contextMap.WithAssemblyContaining <Movement>(); var aggregateType = (contextMap as IBoundedContextModel).GetAggregateType(typeof(CreateLocation)); Assert.IsNotNull(aggregateType); Assert.IsTrue(aggregateType == typeof(Location)); }
public void WithDomainObjectResolverTest() { var resolver = new Mock <IDomainObjectResolver>(); resolver.Setup(x => x.New <Location>()).Returns(new Location()); var context = new BoundedContextModel().WithDomainObjectResolver(resolver.Object); context.DomainObjectResolver.New <Location>(); resolver.Verify(x => x.New <Location>()); }
public HostProcess(BoundedContextModel model) { _projections = new ProjectionManager( model.Services.GetRequiredService <IEventStore>(), model.Services.GetRequiredService <IInboundMessageBus>(), model.Projections.Select(c => c.CreateInstance(model.Services)) ); _aggregates = new AggregateManager( model.Aggregates, model.Services.GetRequiredService <IEventStore>(), model.Services.GetRequiredService <IInboundMessageBus>(), model.Services.GetRequiredService <IEventBus>(), model.Services); }
public void ProcessTwoSequentialCommandsTest() { var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>(); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, DomainOptions.Defaults); var item = new StockItem("item", "123"); var results1 = engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>("c1", "c1", "ar1", new CreateLocation("locationA"))); var results2 = engine.Process(CommandFactory.Default.CreateCommand <AdjustIn>("c2", "c1", "ar1", new AdjustIn($"adjustment_{Guid.NewGuid()}", "locationA", item))); Assert.IsNotNull(results1.FirstOrDefault(e => e.EventBody is LocationCreated)); Assert.IsNotNull(results2.FirstOrDefault(e => e.EventBody is AdjustedIn)); }
public void AggregateAndStatefulProcessEventsTest() { string firstAggregateId = "ar1"; string secondAggregateId = "ar2"; string firstCommandId = "c1"; string secondCommandId = "c2"; string thirdCommandId = "c3"; string fourthCommandId = "c4"; var item = new StockItem("item", "123"); string movementNumber = $"movement_{Guid.NewGuid()}"; var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel() //.WithAssemblyContaining<Location>() .WithAggregateRoot <Location>() .WithEventHandler <MovedOut, Movement, MoveIn>(e => e.EventBody.Movement.ToString(), c => c.Location) .WithEventHandler <MovedIn, Movement>(e => e.EventBody.Movement.ToString()); var options = new DomainOptions(DomainOption.CacheRuntimeModel); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, options); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>(firstCommandId, firstCommandId, firstAggregateId, new CreateLocation(firstAggregateId))); engine.Process(CommandFactory.Default.CreateCommand <AdjustIn>(secondCommandId, secondCommandId, firstAggregateId, new AdjustIn($"adjustment_{Guid.NewGuid()}", firstAggregateId, item))); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>(thirdCommandId, thirdCommandId, secondAggregateId, new CreateLocation(secondAggregateId))); var results = engine.Process(CommandFactory.Default.CreateCommand <MoveOut>(fourthCommandId, fourthCommandId, firstAggregateId, new MoveOut(movementNumber, firstAggregateId, item, secondAggregateId))).ToList(); Assert.IsTrue(results.Count == 2); Assert.IsInstanceOfType(results[0].EventBody, typeof(MovedOut)); Assert.IsTrue(results[0].AggregateId == firstAggregateId); Assert.IsTrue(results[0].AggregateType == typeof(Location).FullName); Assert.IsTrue(results[0].AggregateVersion == 3); Assert.IsTrue(results[0].CommandId == fourthCommandId); Assert.IsTrue(results[0].CorrelationId == fourthCommandId); Assert.IsTrue(results[0].EventBodyType == typeof(MovedOut).FullName); Assert.IsTrue(results[0].Id == $"{firstAggregateId}\\{results[0].AggregateVersion}"); Assert.IsInstanceOfType(results[1].EventBody, typeof(MovedIn)); Assert.IsTrue(results[1].AggregateId == secondAggregateId); Assert.IsTrue(results[1].AggregateType == typeof(Location).FullName); Assert.IsTrue(results[1].AggregateVersion == 2); Assert.IsTrue(results[1].CommandId == $"{typeof(Movement).Name}\\{movementNumber}\\{1}"); Assert.IsTrue(results[1].CorrelationId == fourthCommandId); Assert.IsTrue(results[1].EventBodyType == typeof(MovedIn).FullName); Assert.IsTrue(results[1].Id == $"{secondAggregateId}\\{results[1].AggregateVersion}"); }
public void ExeptionIsThrownTest() { string commandId = "c1"; string experimentId = Guid.NewGuid().ToString(); var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Experiment>(); var options = new DomainOptions(DomainOption.CacheRuntimeModel); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, options); Assert.ThrowsException <ApplicationException>(() => { engine.Process(CommandFactory.Default.CreateCommand <PerformBadExperiment>(commandId, commandId, experimentId, new PerformBadExperiment(true))); }); }
public void ProcessTwoSequentialCommandsUsingDefaultHandlersTest() { var eventStore = new Mock <IEventStore>(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>(); eventStore.Setup(x => x.RetrieveById(It.IsAny <string>())).Returns(new Collection <IEvent>()); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore.Object, DomainOptions.Defaults); var item = new StockItem("item", "123"); var results1 = engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>("c1", "c1", "ar1", new CreateLocation("locationA"))); var results2 = engine.Process(CommandFactory.Default.CreateCommand <AdjustIn>("c2", "c1", "ar1", new AdjustIn($"adjustment_{Guid.NewGuid()}", "locationA", item))); Assert.IsNotNull(results1.FirstOrDefault(e => e.EventBody is LocationCreated)); Assert.IsNotNull(results2.FirstOrDefault(e => e.EventBody is AdjustedIn)); }
public void MultipleOptionalEventsAllNullTest() { string commandId = "c1"; string experimentId = Guid.NewGuid().ToString(); var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Experiment>(); var options = new DomainOptions(DomainOption.CacheRuntimeModel); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, options); var results = engine.Process(CommandFactory.Default.CreateCommand <PerformExperiment>(commandId, commandId, experimentId, new PerformExperiment(false, false))); Assert.IsTrue(results.Count() == 0); }
public void ExeptionIsWrappedInEventTest() { string commandId = "c1"; string experimentId = Guid.NewGuid().ToString(); var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Experiment>().WithExceptionEvent <BadEvent>((e) => new BadEvent(e)); var options = new DomainOptions(DomainOption.CacheRuntimeModel); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, options); var result = engine.Process(CommandFactory.Default.CreateCommand <PerformBadExperiment>(commandId, commandId, experimentId, new PerformBadExperiment(true))); Assert.IsNotNull(result.FirstOrDefault(e => e.EventBody is BadEvent)); }
public void CommandReturnsAssociatedEvent() { var aggregateRoot = new Location(); var command = new CreateLocation("locationName"); var contextMap = new BoundedContextModel().WithAssemblyContaining <Location>(); var aggregateAdapter = AggregateAdapterFactory.Default.CreateAggregate(contextMap, aggregateRoot); var commandAdapter = CommandFactory.Default.CreateCommand <CreateLocation>("command1", "correlationId", "aggregateId", command); var events = aggregateAdapter.ProcessCommand(commandAdapter); Assert.IsNotNull(events); var locationCreatedDomainEvent = events.ToList().FirstOrDefault(); Assert.IsInstanceOfType(locationCreatedDomainEvent, typeof(IEvent)); Assert.IsInstanceOfType((locationCreatedDomainEvent as IEvent).EventBody, typeof(LocationCreated)); }
public void ProcessEventWithRehydrating() { var boundedContextModel = new BoundedContextModel().WithEventHandler <MovedOut, Movement, MoveIn>(e => e.EventBody.Movement, c => c.Location); var eventHandlerAdapter = new EventHandlerAdapter <Movement>(new Movement(), boundedContextModel).WithId("movement"); var item = new StockItem("item", "123"); var myHistoryEvent = EventFactory.Default.CreateEvent <Location, MovedOut>("sourceLocation", 2, "CommandId", "CoorrelationId", new MovedOut("movement", "sourceLocation", item, "destinationLocation")); eventHandlerAdapter.Rehydrate(new[] { myHistoryEvent }); var myEvent = EventFactory.Default.CreateEvent <Location, MovedIn>("destinationLocation", 3, "CommandId2", "CoorrelationId2", new MovedIn("movement", "destinationLocation", item, "sourceLocation")); eventHandlerAdapter.ProcessEvent(myEvent); Assert.AreEqual(1, eventHandlerAdapter.UncommittedChanges.Count()); Assert.AreEqual(2, eventHandlerAdapter.UncommittedChanges.First().AggregateVersion); }
public void ProcessCommandUsingDefaultHandlerTest() { var commandId = "command1"; var correlationId = "command1"; var aggregateId = "location1"; var eventStore = new Mock <IEventStore>(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>(); eventStore.Setup(x => x.RetrieveById(It.IsAny <string>())).Returns(new Collection <IEvent>()); var item = new StockItem("item", "123"); var command = CommandFactory.Default.CreateCommand <MoveIn>(commandId, correlationId, aggregateId, new MoveIn($"movement_{Guid.NewGuid()}", "locationA", item, "locationB")); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore.Object, DomainOptions.Defaults); engine.Process(command); }
public void ProcessCommandUsingCustomHandlerTest() { var commandId = "command1"; var correlationId = "command1"; var aggregateId = "location1"; var contextModel = new BoundedContextModel() .WithAssemblyContaining <Location>() .WithCommandHandler <MoveIn, Location, MovedIn>(); var eventStore = new InMemoryEventStore(); var item = new StockItem("item", "123"); var command = CommandFactory.Default.CreateCommand <MoveIn>(commandId, correlationId, aggregateId, new MoveIn($"movement_{Guid.NewGuid()}", "locationA", item, "locationB")); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, DomainOptions.Defaults); engine.Process(command); }
public void RehydrateAggregateFailsIfEventAggregateIdMismatch() { var aggregateId = Guid.NewGuid().ToString(); var locationName = "location1"; var item = new StockItem("item1", "1"); var contextMap = new BoundedContextModel().WithAssemblyContaining <Location>(); var aggregateRoot = new Location(); var aggregateAdapter = AggregateAdapterFactory.Default.CreateAggregate(contextMap, aggregateRoot).WithId(aggregateId); var eventAdapterFactory = new EventFactory(); var aggregateEventHistory = new List <IEvent>(); aggregateEventHistory.Add(eventAdapterFactory.CreateEvent <Location, LocationCreated>(aggregateId, 1, string.Empty, string.Empty, new LocationCreated(locationName, string.Empty))); aggregateEventHistory.Add(eventAdapterFactory.CreateEvent <Location, AdjustedIn>(aggregateId, 2, string.Empty, string.Empty, new AdjustedIn($"adjustment_{Guid.NewGuid()}", locationName, item))); aggregateEventHistory.Add(eventAdapterFactory.CreateEvent <Location, MovedOut>(Guid.NewGuid().ToString(), 3, string.Empty, string.Empty, new MovedOut($"movement_{Guid.NewGuid()}", locationName, item, "toLocationName"))); Assert.ThrowsException <ArgumentException>(() => aggregateAdapter.Rehydrate(aggregateEventHistory)); }
public void AggregateEventTest() { string aggregateId = "ar1"; string commandId = "c1"; var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>(); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, DomainOptions.Defaults); var result = engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>(commandId, commandId, aggregateId, new CreateLocation(aggregateId))).Single(); Assert.IsInstanceOfType(result.EventBody, typeof(LocationCreated)); Assert.IsTrue(result.AggregateId == aggregateId); Assert.IsTrue(result.AggregateType == typeof(Location).FullName); Assert.IsTrue(result.AggregateVersion == 1); Assert.IsTrue(result.CommandId == commandId); Assert.IsTrue(result.CorrelationId == commandId); Assert.IsTrue(result.EventBodyType == typeof(LocationCreated).FullName); Assert.IsTrue(result.Id == $"{aggregateId}\\{result.AggregateVersion}"); }
public void SimpleProcessUpdatesTwoAggregatesUsingDefaultHandlersTest() { var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>(); var aggregateModel = new RuntimeModel(contextModel, eventStore); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, DomainOptions.Defaults); var item = new StockItem("item", "123"); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>("c1", "c1", "ar1", new CreateLocation("ar1"))); engine.Process(CommandFactory.Default.CreateCommand <AdjustIn>("c2", "c1", "ar1", new AdjustIn($"adjustment_{Guid.NewGuid()}", "ar1", item))); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>("c3", "c3", "ar2", new CreateLocation("ar2"))); var results = engine.Process(CommandFactory.Default.CreateCommand <MoveOut>("c3", "c3", "ar1", new MoveOut($"movement_{Guid.NewGuid()}", "ar1", item, "ar2"))); var movedOutEvent = results.FirstOrDefault(e => e.EventBody is MovedOut); var movedInEvent = results.FirstOrDefault(e => e.EventBody is MovedIn); Assert.IsNotNull(movedOutEvent); Assert.IsNotNull(movedInEvent); }
public void IocUsingUnityTest() { var unityContainer = new UnityContainer(); unityContainer.RegisterType <Location>(); unityContainer.RegisterType <InventoryItem>(); var domainObjectFactory = new UnityDomainObjectFactory(unityContainer); var eventStore = new Mock <IEventStore>(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>().WithDomainObjectResolver(domainObjectFactory); eventStore.Setup(x => x.RetrieveById(It.IsAny <string>())).Returns(new Collection <IEvent>()); var command1 = CommandFactory.Default.CreateCommand <CreateLocation>(id: "C1", aggregateId: "Location 1", command: new CreateLocation("Location 1")); var command2 = CommandFactory.Default.CreateCommand <CreateInventoryItem>(id: "C2", aggregateId: "Item A", command: new CreateInventoryItem("Item A")); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore.Object, DomainOptions.Defaults); engine.Process(command1); engine.Process(command2); }
public void IoCUsingNijectTest() { var ninjectKernel = new StandardKernel(); ninjectKernel.Bind <Location>().To <Location>(); ninjectKernel.Bind <InventoryItem>().To <InventoryItem>(); var domainObjectFactory = new NinjectDomainObjectFactory(ninjectKernel); var eventStore = new Mock <IEventStore>(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>().WithDomainObjectResolver(domainObjectFactory); var domainModel = new RuntimeModel(contextModel, eventStore.Object); eventStore.Setup(x => x.RetrieveById(It.IsAny <string>())).Returns(new Collection <IEvent>()); var command1 = CommandFactory.Default.CreateCommand <CreateLocation>(id: "C1", aggregateId: "Location 1", command: new CreateLocation("Location 1")); var command2 = CommandFactory.Default.CreateCommand <CreateInventoryItem>(id: "C2", aggregateId: "Item A", command: new CreateInventoryItem("Item A")); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore.Object, DomainOptions.Defaults); engine.Process(command1); engine.Process(command2); }
public void CommandIsIdempotent() { string aggregateId = "ar1"; string commandId = "c1"; string adjustmentId = "adjust1"; var item = new StockItem("item", "123"); var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>(); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, DomainOptions.Defaults); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>("c0", "c0", aggregateId, new CreateLocation(aggregateId))).Single(); var command = CommandFactory.Default.CreateCommand <AdjustIn>(commandId, commandId, aggregateId, new AdjustIn(adjustmentId, aggregateId, item)); var firstResults = engine.Process(command); var secondResults = engine.Process(command); Assert.IsTrue(firstResults.Any(e => e.EventBody is AdjustedIn)); Assert.IsFalse(secondResults.Any(e => e.EventBody is AdjustedIn)); }
public void SimpleProcessUpdatesTwoAggregatesAndFinalEventHandlerUsingDefaultHandlersTest() { var eventStore = new InMemoryEventStore(); var contextModel = new BoundedContextModel() .WithAssemblyContaining <Location>() .WithEventHandler <TestEventHandler>(); var aggregateModel = new RuntimeModel(contextModel, eventStore); var item = new StockItem("item", "123"); items.Clear(); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore, DomainOptions.Defaults); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>("c1", "c1", "ar1", new CreateLocation("ar1"))); engine.Process(CommandFactory.Default.CreateCommand <AdjustIn>("c2", "c1", "ar1", new AdjustIn($"adjustment_{Guid.NewGuid()}", "ar1", item))); engine.Process(CommandFactory.Default.CreateCommand <CreateLocation>("c3", "c3", "ar2", new CreateLocation("ar2"))); var results = engine.Process(CommandFactory.Default.CreateCommand <MoveOut>("c3", "c3", "ar1", new MoveOut($"movement_{Guid.NewGuid()}", "ar1", item, "ar2"))); Assert.AreEqual(1, items.Count); Assert.AreEqual(item, items[0]); }
public void IoCUsingCustomMethodTest() { var domainObjectResolver = new Mock <IDomainObjectResolver>(); domainObjectResolver.Setup(x => x.New <Location>()).Returns(new Location()); domainObjectResolver.Setup(x => x.New <InventoryItem>()).Returns(new InventoryItem()); domainObjectResolver.Setup(x => x.New(It.Is <Type>(x => x == typeof(Location)))).Returns(new Location()).Verifiable(); domainObjectResolver.Setup(x => x.New(It.Is <Type>(x => x == typeof(InventoryItem)))).Returns(new InventoryItem()).Verifiable(); var eventStore = new Mock <IEventStore>(MockBehavior.Loose); var contextModel = new BoundedContextModel().WithAssemblyContaining <Location>().WithDomainObjectResolver(domainObjectResolver.Object); eventStore.Setup(x => x.RetrieveById(It.IsAny <string>(), It.IsAny <int>())).Returns(new Collection <IEvent>()); var command1 = CommandFactory.Default.CreateCommand <CreateLocation>(id: "C1", aggregateId: "Location 1", command: new CreateLocation("Location 1")); var command2 = CommandFactory.Default.CreateCommand <CreateInventoryItem>(id: "C2", aggregateId: "Item A", command: new CreateInventoryItem("Item A")); var engine = DomainFactory.CreateDomainExecutionEngine(contextModel, eventStore.Object, DomainOptions.Defaults); engine.Process(command1); engine.Process(command2); domainObjectResolver.VerifyAll(); }
public BoundedContextModelTests() { var aggregate = new AggregateModel(typeof(Domains.Airline.FlightReservation)); Model = new BoundedContextModel(new [] { aggregate }); }
public void MapAppDomainTest() { var contextMap = new BoundedContextModel(); contextMap.WithAllAppDomainAssemblies(); }
public AggregateManager(BoundedContextModel model, IEventStore store, IServiceProvider svcs) { Model = model; Store = store; Services = svcs; }