/// <summary>
        /// Processes the events.
        /// </summary>
        /// <param name="aggregate">The aggregate.</param>
        /// <param name="resolvedEvents">The resolved events.</param>
        /// <returns></returns>
        private TAggregate ProcessEvents(TAggregate aggregate,
                                         IList <ResolvedEvent> resolvedEvents)
        {
            if (resolvedEvents != null && resolvedEvents.Count > 0)
            {
                List <IDomainEvent> domainEvents = new();

                foreach (var resolvedEvent in resolvedEvents)
                {
                    IDomainEvent domainEvent = TypeMapConvertor.Convertor(aggregate.AggregateId, resolvedEvent);

                    domainEvents.Add(domainEvent);
                }

                return(domainEvents.Aggregate(aggregate,
                                              (aggregate1,
                                               @event) =>
                {
                    try
                    {
                        aggregate1.Apply(@event);
                        return aggregate1;
                    }
                    catch (Exception e)
                    {
                        Exception ex = new Exception($"Failed to apply domain event {@event.EventType} to Aggregate {aggregate.GetType()} ",
                                                     e);
                        throw ex;
                    }
                }));
            }

            return(aggregate);
        }
        /// <summary>
        /// Saves the changes.
        /// </summary>
        /// <param name="aggregate">The aggregate.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        public async Task SaveChanges(TAggregate aggregate,
                                      CancellationToken cancellationToken)
        {
            String streamName = AggregateRepository <TAggregate, TDomainEvent> .GetStreamName(aggregate.AggregateId);

            IList <IDomainEvent> pendingEvents = aggregate.GetPendingEvents();

            if (!pendingEvents.Any())
            {
                return;
            }

            List <EventData> events = new();

            foreach (IDomainEvent domainEvent in pendingEvents)
            {
                EventData @event = TypeMapConvertor.Convertor(domainEvent);

                events.Add(@event);
            }

            await this.EventStoreContext.InsertEvents(streamName, aggregate.Version, events, cancellationToken);

            aggregate.CommitPendingEvents();
        }
Example #3
0
        /// <summary>
        /// Convertors the specified aggregate identifier.
        /// </summary>
        /// <param name="aggregateId">The aggregate identifier.</param>
        /// <param name="event">The event.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">Could not find EventType {eventType.Name} in mapping list.</exception>
        public static IDomainEvent Convertor(Guid aggregateId,
                                             ResolvedEvent @event)
        {
            //TODO: We could pass this Type into GetDomainEvent(s)
            var eventType = TypeMap.GetType(@event.Event.EventType);

            if (eventType.IsSubclassOf(typeof(DomainEvent)))
            {
                return(TypeMapConvertor.GetDomainEvent(aggregateId, @event));
            }

            throw new Exception($"Could not find EventType {eventType.Name} in mapping list.");
        }
Example #4
0
 /// <summary>
 /// Convertors the specified event.
 /// </summary>
 /// <param name="event">The event.</param>
 /// <returns></returns>
 public static IDomainEvent Convertor(ResolvedEvent @event) => TypeMapConvertor.Convertor(Guid.Empty, @event);