public EventSourcedAggregateFactoryTests() { eventStreamUpgrader = Substitute.For <IEventStreamUpgrader>(); eventStreamUpgrader.UpgradeStream(null, null).ReturnsForAnyArgs(ci => { var stream = ci.Arg <IEnumerable <IEventMessage <DomainAggregateEvent> > >(); var aggregateMetadata = ci.Arg <IReadOnlyDictionary <string, string> >(); return(eventStreamUpgradeFunc(stream, aggregateMetadata)); }); DomainClassInfo[] domainClasses = new[] { new DomainClassInfo(entity1ClassId, null, typeof(MyEntity)), new DomainClassInfo(entity2ClassId, null, typeof(MyEntity2)) }; entityTypeManager = Substitute.For <IEntityTypeManager>(); entityTypeManager.GetClassInfoByClassId(Guid.Empty) .ReturnsForAnyArgs(ci => domainClasses.Single(x => x.Id == ci.Arg <Guid>())); entityTypeManager.TryGetClassInfoByClrType(null) .ReturnsForAnyArgs(ci => domainClasses.SingleOrDefault(x => x.ClrType == ci.Arg <Type>())); entityTypeManager.GetClassInfoByClrType(null) .ReturnsForAnyArgs(ci => domainClasses.Single(x => x.ClrType == ci.Arg <Type>())); sut = new EventSourcedAggregateFactory(eventStreamUpgrader, new EntityFactory(), entityTypeManager); }
public IEventSourcedAggregateRoot ConstructAndLoadEntityFromEvents(Guid aggregateId, IReadOnlyDictionary <string, string> eventStreamMetadata, IReadOnlyCollection <IEventStoreRecord> eventRecords) { if (!eventStreamMetadata.TryGetValue(AggregateEventStreamMetadataNames.ClassId, out string classIdString)) { throw new InvalidOperationException($"Cannot load event sourced aggregate ID {aggregateId}: aggregate class ID not found in event stream metadata"); } Guid classId = Guid.Parse(classIdString); Type entityType = entityTypeManager.GetClassInfoByClassId(classId).ClrType; IEnumerable <IEventMessage <DomainAggregateEvent> > eventMessages; try { eventMessages = eventRecords.Select(EventStoreEventMessage.FromRecord) .Cast <IEventMessage <DomainAggregateEvent> >(); } catch (InvalidCastException e) { throw new InvalidOperationException( $"Cannot load event sourced aggregate ID {aggregateId}: event stream contains non-DomainAggregateEvent events", e); } var upgradedEvents = eventStreamUpgrader.UpgradeStream(eventMessages, eventStreamMetadata); var events = upgradedEvents.Select(x => x.Event).ToArray(); int version = (int)(eventRecords.LastOrDefault()?.AdditionalMetadata.GetAggregateVersion() // use non-upgraded event records to preserve the versions ?? eventRecords.LastOrDefault()?.StreamSequenceNumber ?? 0); AggregateState state = new AggregateState(version, events); IEventSourcedAggregateRoot aggregate = (IEventSourcedAggregateRoot)ConstructEntity(entityType, aggregateId); aggregate.LoadState(state); return(aggregate); }