Example #1
0
            public Task InitializeAsync()
            {
                var eventTypes = _eventAssemblies
                                 .SelectMany(x => x.Assembly.GetTypes())
                                 .Where(t => !t.GetTypeInfo().IsAbstract&& typeof(IAggregateEvent).GetTypeInfo().IsAssignableFrom(t))
                                 .ToArray();

                var unnamedEvents = eventTypes
                                    .Where(t => t.GetCustomAttribute <EventVersionAttribute>() == null)
                                    .ToArray();

                if (unnamedEvents.Any())
                {
                    var eventNames = string.Join("\n", unnamedEvents.Select(t => t.FullName));
                    throw new ApplicationException($"Following events do not have {nameof(EventVersionAttribute)} applied to them:\n{eventNames}");
                }

                var duplicateEvents = eventTypes
                                      .GroupBy(x => ExtractEventName(x))
                                      .Where(x => x.Count() > 1)
                                      .ToArray();

                if (duplicateEvents.Any())
                {
                    var messages = duplicateEvents.Select(x => $"name {x.Key} is used by events: {string.Join(", ", x.Select(y => y.FullName))}");
                    throw new ApplicationException($"Ambiguous events found:\n{string.Join("\n", messages)}");
                }

                _eventDefinitionService.Load(eventTypes);

                return(Task.CompletedTask);
            }
        public Task BootAsync(CancellationToken cancellationToken)
        {
            _commandDefinitionService.Load(_loadedVersionedTypes.Commands);
            _eventDefinitionService.Load(_loadedVersionedTypes.Events);
            _jobDefinitionService.Load(_loadedVersionedTypes.Jobs);

            return(Task.FromResult(0));
        }
Example #3
0
        private object FromObject(object aggregateEvent, long version, IMetadata metadata = null)
        {
            if (aggregateEvent is IAggregateEvent)
            {
                _eventDefinitionService.Load(aggregateEvent.GetType());
                var eventDefinition         = _eventDefinitionService.GetDefinition(aggregateEvent.GetType());
                var aggregateSequenceNumber = version + 1;
                var eventId = EventId.NewDeterministic(
                    GuidFactories.Deterministic.Namespaces.Events,
                    $"{Id.Value}-v{aggregateSequenceNumber}");
                var now           = DateTimeOffset.UtcNow;
                var eventMetadata = new Metadata
                {
                    Timestamp = now,
                    AggregateSequenceNumber = aggregateSequenceNumber,
                    AggregateName           = Name.Value,
                    AggregateId             = Id.Value,
                    SourceId     = PinnedCommand.SourceId,
                    EventId      = eventId,
                    EventName    = eventDefinition.Name,
                    EventVersion = eventDefinition.Version
                };
                eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString());
                if (metadata != null)
                {
                    eventMetadata.AddRange(metadata);
                }
                var genericType = typeof(CommittedEvent <, ,>)
                                  .MakeGenericType(typeof(TAggregate), typeof(TIdentity), aggregateEvent.GetType());


                var committedEvent = Activator.CreateInstance(
                    genericType,
                    Id,
                    aggregateEvent,
                    eventMetadata,
                    now,
                    aggregateSequenceNumber);

                return(committedEvent);
            }

            throw new InvalidOperationException("could not perform the required mapping for committed event.");
        }
Example #4
0
        private void RegisterAllEvents()
        {
            var eventAssembly       = typeof(ReservationCreated).Assembly;
            var aggregateEventTypes = eventAssembly
                                      .GetTypes()
                                      .Where(t => IsAssignableToGenericType(t, typeof(IAggregateEvent <,>)))
                                      .ToImmutableList();

            _eventDefinitionService.Load(aggregateEventTypes);
        }
Example #5
0
        public virtual CommittedEvent <TAggregate, TIdentity, TAggregateEvent> From <TAggregateEvent>(TAggregateEvent aggregateEvent,
                                                                                                      long version, IMetadata metadata = null)
            where TAggregateEvent : IAggregateEvent <TAggregate, TIdentity>
        {
            if (aggregateEvent == null)
            {
                throw new ArgumentNullException(nameof(aggregateEvent));
            }
            _eventDefinitionService.Load(aggregateEvent.GetType());
            var eventDefinition         = _eventDefinitionService.GetDefinition(aggregateEvent.GetType());
            var aggregateSequenceNumber = version + 1;
            var eventId = EventId.NewDeterministic(
                GuidFactories.Deterministic.Namespaces.Events,
                $"{Id.Value}-v{aggregateSequenceNumber}");
            var now           = DateTimeOffset.UtcNow;
            var eventMetadata = new Metadata
            {
                Timestamp = now,
                AggregateSequenceNumber = aggregateSequenceNumber,
                AggregateName           = Name.Value,
                AggregateId             = Id.Value,
                SourceId     = PinnedCommand.SourceId,
                EventId      = eventId,
                EventName    = eventDefinition.Name,
                EventVersion = eventDefinition.Version
            };

            eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString());
            if (metadata != null)
            {
                eventMetadata.AddRange(metadata);
            }

            var committedEvent = new CommittedEvent <TAggregate, TIdentity, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, aggregateSequenceNumber);

            return(committedEvent);
        }
Example #6
0
        public virtual void Emit <TAggregateEvent>(TAggregateEvent aggregateEvent, IMetadata metadata = null)
            where TAggregateEvent : IAggregateEvent <TAggregate, TIdentity>
        {
            if (aggregateEvent == null)
            {
                throw new ArgumentNullException(nameof(aggregateEvent));
            }
            _eventDefinitionService.Load(typeof(TAggregateEvent));
            var eventDefinition         = _eventDefinitionService.GetDefinition(typeof(TAggregateEvent));
            var aggregateSequenceNumber = Version + 1;
            var eventId = EventId.NewDeterministic(
                GuidFactories.Deterministic.Namespaces.Events,
                $"{Id.Value}-v{aggregateSequenceNumber}");
            var now           = DateTimeOffset.UtcNow;
            var eventMetadata = new Metadata
            {
                Timestamp = now,
                AggregateSequenceNumber = aggregateSequenceNumber,
                AggregateName           = Name.Value,
                AggregateId             = Id.Value,
                EventId      = eventId,
                EventName    = eventDefinition.Name,
                EventVersion = eventDefinition.Version
            };

            eventMetadata.Add(MetadataKeys.TimestampEpoch, now.ToUnixTime().ToString());
            if (metadata != null)
            {
                eventMetadata.AddRange(metadata);
            }

            var committedEvent = new CommittedEvent <TAggregate, TIdentity, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, Version);

            Persist(committedEvent, ApplyCommittedEvents);

            Logger.Info($"[{Name}] With Id={Id} Commited [{typeof(TAggregateEvent).PrettyPrint()}]");

            Version++;

            var domainEvent = new DomainEvent <TAggregate, TIdentity, TAggregateEvent>(Id, aggregateEvent, eventMetadata, now, Version);

            Publish(domainEvent);

            if (SnapshotStrategy.ShouldCreateSnapshot(this))
            {
                var aggregateSnapshot = CreateSnapshot();
                if (aggregateSnapshot != null)
                {
                    var t = aggregateSnapshot.GetType();
                    _snapshotDefinitionService.Load(aggregateSnapshot.GetType());
                    var snapshotDefinition = _snapshotDefinitionService.GetDefinition(aggregateSnapshot.GetType());
                    var snapshotMetadata   = new SnapshotMetadata
                    {
                        AggregateId             = Id.Value,
                        AggregateName           = Name.Value,
                        AggregateSequenceNumber = Version,
                        SnapshotName            = snapshotDefinition.Name,
                        SnapshotVersion         = snapshotDefinition.Version
                    };

                    var commitedSnapshot =
                        new ComittedSnapshot <TAggregate, TIdentity, IAggregateSnapshot <TAggregate, TIdentity> >(
                            Id,
                            aggregateSnapshot,
                            snapshotMetadata,
                            now, Version);
                    SaveSnapshot(commitedSnapshot);
                }
            }
        }